{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 数据集回顾\n",
    "\n",
    "在进行数据处理前，我们先回顾下本章使用的ml-1m电影推荐数据集。\n",
    "\n",
    "ml-1m是GroupLens Research从MovieLens网站上收集并提供的电影评分数据集。包含了6000多位用户对近3900个电影的共100万条评分数据，评分均为1～5的整数，其中每个电影的评分数据至少有20条。该数据集包含三个数据文件，分别是：\n",
    "- users.dat，存储用户属性信息的文本格式文件。\n",
    "- movies.dat，存储电影属性信息的文本格式文件。\n",
    "- ratings.dat， 存储电影评分信息的文本格式文件。\n",
    "\n",
    "电影海报图像在posters文件夹下，海报图像的名字以\"mov_id\" + 电影ID + \".png\"的方式命名。由于这里的电影海报图像有缺失，我们整理了一个新的评分数据文件，新的文件中包含的电影均是有海报数据的，因此，本次实验使用的数据集在ml-1m基础上增加了两份数据：\n",
    "- posters, 包含电影海报图像。\n",
    "- new_rating.txt， 包含海报图像的评分数据文件（从原始评分数据中过滤得到）。\n",
    "\n",
    "注意：海报图像的数据将不在本实验中使用，而留作本章的作业。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 数据处理流程\n",
    "\n",
    "在计算机视觉和自然语言处理章节中，我们已经了解到数据处理是算法应用的前提，并掌握了图像数据处理和自然语言数据处理的方法。总结一下，数据处理就是将人类容易理解的图像文本数据，转换为机器容易理解的数字形式，把离散的数据转为连续的数据。在推荐算法中，这些数据处理方法也是通用的。\n",
    "\n",
    "本次实验中，数据处理一共包含如下六步：\n",
    "\n",
    "1. 读取用户数据，存储到字典。\n",
    "2. 读取电影数据，存储到字典。\n",
    "3. 读取评分数据，存储到字典。\n",
    "4. 读取海报数据，存储到字典。\n",
    "5. 将各个字典中的数据拼接，形成数据读取器。\n",
    "6. 划分训练集和验证集，生成迭代器，每次提供一个批次的数据。\n",
    "\n",
    "流程如下图所示。\n",
    "\n",
    "<center><img src=\"https://ai-studio-static-online.cdn.bcebos.com/8ff78137536c4da68907fe92c24baeddb0446deba5cc4489beb078ce5726980a\" width=\"500\" ></center>\n",
    "\n",
    "<center><br>图1：数据处理流程图 </br></center>\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 用户数据处理\n",
    "\n",
    "\n",
    "用户数据文件user.dat中的数据格式为：UserID::Gender::Age::Occupation::Zip-code，存储形式如下图所示：\n",
    "<br></br>\n",
    "<img src=\"https://ai-studio-static-online.cdn.bcebos.com/7a5fd5c791634b48a56c28c92266680941c10f467f8b47a6bbe8c3603088c23f\" width=\"300\" >\n",
    "\n",
    "上图中，每一行表示一个用户的数据，以$::$隔开，第一列到最后一列分别表示UserID、Gender、Age、Occupation、Zip-code，各数据对应关系如下:\n",
    "\n",
    "\n",
    "| 数据类别 | 数据说明 | 数据示例 |\n",
    "| -------- | -------- | -------- |\n",
    "| **UserID**   | 每个用户的数字代号| 1、2、3等序号     |\n",
    "| **Gender**     | F表示女性，M表示男性| F或M     |\n",
    "| **Age**     | 用数字表示各个年龄段| <ul><li>1: \"Under 18\"　　　　　　　　　　　　　　　　　　　　　　</li><li>18: \"18-24\"</li>  <li>25: \"25-34\"</li>  <li>35: \"35-44\"</li>  <li>45: \"45-49\"</li>  <li>50: \"50-55\"</li>  <li>56: \"56+\"</li></ul> |\n",
    "| **Occupation**     | 用数字表示不同职业     | <ul><li>0: \"other\" or not specified</li><li>1: \"academic/educator\"</li> <li>2: \"artist\"</li>  <li>3: \"clerical/admin\"</li>  <li>4: \"college/grad student\"</li>  <li>5: \"customer service\"</li> <li>6: \"doctor/health care\"</li>  <li>7: \"executive/managerial\"</li>  <li>8: \"farmer\"</li>  <li>9: \"homemaker\"</li>  <li>10: \"K-12 student\"</li>  <li>11: \"lawyer\"</li>  <li>12: \"programmer\"</li>  <li>13: \"retired\"</li>  <li>14: \"sales/marketing\"</li> <li>15: \"scientist\"</li>  <li>16: \"self-employed\"</li>  <li>17: \"technician/engineer\"</li>  <li>18: \"tradesman/craftsman\"</li>  <li>19: \"unemployed\"</li>  <li>20: \"writer\"</li>  </ul>|\n",
    "| **zip-code**     | 邮政编码，与用户所处的地理位置有关。<br>在本次实验中，不使用这个数据。    | 48067     |\n",
    "\n",
    "\n",
    "><font size=2>比如82::M::25::17::48380表示ID为82的用户，性别为男，年龄为25-34岁，职业为technician/engineer。</font>\n",
    "\n",
    "首先，读取用户信息文件中的数据："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 解压数据集\n",
    "!unzip -o -q -d ~/work/ ~/data/data19736/ml-1m.zip"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data 数据长度是： 6040\n",
      "第一条数据是： 1::F::1::10::48067\n",
      "\n",
      "数据类型： <class 'str'>\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "usr_file = \"./work/ml-1m/users.dat\"\n",
    "# 打开文件，读取所有行到data中\n",
    "with open(usr_file, 'r') as f:\n",
    "    data = f.readlines()\n",
    "# 打印data的数据长度、第一条数据、数据类型\n",
    "print(\"data 数据长度是：\",len(data))\n",
    "print(\"第一条数据是：\", data[0])\n",
    "print(\"数据类型：\", type(data[0]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "观察以上结果，用户数据一共有6040条，以 $::$ 分隔，是字符串类型。为了方便后续数据读取，区分用户的ID、年龄、职业等数据，一个简单的方式是将数据存储到字典中。另外在自然语言处理章节中我们了解到，文本数据无法直接输入到神经网络中进行计算，所以需要将字符串类型的数据转换成数字类型。\n",
    "另外，用户的性别F、M是字母数据，这里需要转换成数字表示。\n",
    "\n",
    "我们定义如下函数实现字母转数字，将性别M、F转成数字0、1表示。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "性别M用数字 0 表示\n",
      "性别F用数字 1 表示\n"
     ]
    }
   ],
   "source": [
    "def gender2num(gender):\n",
    "    return 1 if gender == 'F' else 0\n",
    "print(\"性别M用数字 {} 表示\".format(gender2num('M')))\n",
    "print(\"性别F用数字 {} 表示\".format(gender2num('F')))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "接下来把用户数据的字符串类型的数据转成数字类型，并存储到字典中，实现如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "用户ID为3的用户数据是： {'usr_id': 3, 'gender': 0, 'age': 25, 'job': 15}\n"
     ]
    }
   ],
   "source": [
    "usr_info = {}\n",
    "max_usr_id = 0\n",
    "#按行索引数据\n",
    "for item in data:\n",
    "    # 去除每一行中和数据无关的部分\n",
    "    item = item.strip().split(\"::\")\n",
    "    usr_id = item[0]\n",
    "    # 将字符数据转成数字并保存在字典中\n",
    "    usr_info[usr_id] = {'usr_id': int(usr_id),\n",
    "                        'gender': gender2num(item[1]),\n",
    "                        'age': int(item[2]),\n",
    "                        'job': int(item[3])}\n",
    "    max_usr_id = max(max_usr_id, int(usr_id))\n",
    "\n",
    "print(\"用户ID为3的用户数据是：\", usr_info['3'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "至此，我们完成了用户数据的处理，完整的代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "用户数量: 6040\n",
      "最大用户ID: 6040\n",
      "第1个用户的信息是： {'usr_id': 1, 'gender': 1, 'age': 1, 'job': 10}\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "def get_usr_info(path):\n",
    "    # 性别转换函数，M-0， F-1\n",
    "    def gender2num(gender):\n",
    "        return 1 if gender == 'F' else 0\n",
    "    \n",
    "    # 打开文件，读取所有行到data中\n",
    "    with open(path, 'r') as f:\n",
    "        data = f.readlines()\n",
    "    # 建立用户信息的字典\n",
    "    use_info = {}\n",
    "    \n",
    "    max_usr_id = 0\n",
    "    #按行索引数据\n",
    "    for item in data:\n",
    "        # 去除每一行中和数据无关的部分\n",
    "        item = item.strip().split(\"::\")\n",
    "        usr_id = item[0]\n",
    "        # 将字符数据转成数字并保存在字典中\n",
    "        use_info[usr_id] = {'usr_id': int(usr_id),\n",
    "                            'gender': gender2num(item[1]),\n",
    "                            'age': int(item[2]),\n",
    "                            'job': int(item[3])}\n",
    "        max_usr_id = max(max_usr_id, int(usr_id))\n",
    "    \n",
    "    return use_info, max_usr_id\n",
    "\n",
    "usr_file = \"./work/ml-1m/users.dat\"\n",
    "usr_info, max_usr_id = get_usr_info(usr_file)\n",
    "print(\"用户数量:\", len(usr_info))\n",
    "print(\"最大用户ID:\", max_usr_id)\n",
    "print(\"第1个用户的信息是：\", usr_info['1'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "从上面的结果可以得出，一共有6040个用户，其中ID为1的用户信息是{'usr_id': [1], 'gender': [1], 'age': [1], 'job': [10]}，表示用户的性别序号是1（女），年龄序号是1（Under 18），职业序号是10（K-12 student），都已处理成数字类型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 电影数据处理\n",
    "\n",
    "电影信息包含在movies.dat中，数据格式为：MovieID::Title::Genres，保存的格式与用户数据相同，每一行表示一条电影数据信息。\n",
    "<br></br>\n",
    "<img src=\"https://ai-studio-static-online.cdn.bcebos.com/33c577021a674fd3b2ec779216447182bae861b56bd446389c9066d508395f36\" width=\"600\" >\n",
    "\n",
    "各数据对应关系如下：\n",
    "| 数据类别 | 数据说明 | 数据示例 |\n",
    "| -------- | -------- | -------- |\n",
    "| **MovieID**     | 每个电影的数字代号     | 1、2、3等序号    |\n",
    "| **Title**     | 每个电影的名字和首映时间     | 比如：Toy Story (1995)     |\n",
    "| **Genres**     | 电影的种类，每个电影不止一个类别，不同类别以　\\|　隔开    | 比如：Animation\\| Children's\\|Comedy <br>包含的类别有：【Action，Adventure，Animation，Children's，Comedy，Crime，Documentary，Drama，Fantasy，Film-Noir，Horror，Musical，Mystery，Romance，Sci-Fi，Thriller，War，Western】|\n",
    "\n",
    "首先，读取电影信息文件里的数据。需要注意的是，电影数据的存储方式和用户数据不同，在读取电影数据时，需要指定编码方式为\"ISO-8859-1\"："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1::Toy Story (1995)::Animation|Children's|Comedy\n",
      "\n",
      "movie ID: 1\n",
      "movie title: Toy Story\n",
      "movie year: 1995\n",
      "movie genre: ['Animation', \"Children's\", 'Comedy']\n"
     ]
    }
   ],
   "source": [
    "movie_info_path = \"./work/ml-1m/movies.dat\"\n",
    "# 打开文件，编码方式选择ISO-8859-1，读取所有数据到data中\n",
    "with open(movie_info_path, 'r', encoding=\"ISO-8859-1\") as f:\n",
    "    data = f.readlines()\n",
    "\n",
    "# 读取第一条数据，并打印\n",
    "item = data[0]\n",
    "print(item)\n",
    "item = item.strip().split(\"::\")\n",
    "print(\"movie ID:\", item[0])\n",
    "print(\"movie title:\", item[1][:-7])\n",
    "print(\"movie year:\", item[1][-5:-1])\n",
    "print(\"movie genre:\", item[2].split('|'))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "从上述代码，我们看出每条电影数据以 $::$ 分隔，是字符串类型。类似处理用户数据的方式，需要将字符串类型的数据转换成数字类型，存储到字典中。\n",
    "不同的是，在用户数据处理中，我们把性别数据M、F处理成0、1，而电影数据中Title和Genres都是长文本信息，为了便于后续神经网络计算，我们把其中每个单词都拆分出来，不同的单词用对应的数字序号指代。\n",
    "\n",
    "所以，我们需要对这些数据进行如下处理：\n",
    "1. 统计电影ID信息。\n",
    "2. 统计电影名字的单词，并给每个单词一个数字序号。\n",
    "3. 统计电影类别单词，并给每个单词一个数字序号。\n",
    "4. 保存电影数据到字典中，方便根据电影ID进行索引。\n",
    "\n",
    "实现方法如下:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### 1. 统计电影ID信息\n",
    "将电影ID信息存到字典中，并获得电影ID的最大值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "电影的最大ID是： 3952\n"
     ]
    }
   ],
   "source": [
    "movie_info_path = \"./work/ml-1m/movies.dat\"\n",
    "# 打开文件，编码方式选择ISO-8859-1，读取所有数据到data中\n",
    "with open(movie_info_path, 'r', encoding=\"ISO-8859-1\") as f:\n",
    "    data = f.readlines()\n",
    "    \n",
    "movie_info = {}\n",
    "for item in data:\n",
    "    item = item.strip().split(\"::\")\n",
    "    # 获得电影的ID信息\n",
    "    v_id = item[0]\n",
    "    movie_info[v_id] = {'mov_id': int(v_id)}\n",
    "max_id = max([movie_info[k]['mov_id'] for k in movie_info.keys()])\n",
    "print(\"电影的最大ID是：\", max_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### 2. 统计电影名字的单词，并给每个单词一个数字序号\n",
    "\n",
    "不同于用户数据，电影数据中包含文字数据，但神经网络模型无法直接处理文本数据。我们可以借助自然语言处理中word embedding的方式完成文本到数字向量之间的转换。按照word embedding的步骤，需要先将每个单词用数字代替，然后利用embedding的方法完成数字到映射向量之间的转换。此处，我们只需要先完成文本到数字的转换，即把电影名称的单词用数字代替。在读取电影数据的同时，统计出现过的单词，从数字 1 开始对不同单词进行编码。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最大电影title长度是： 15\n",
      "电影 ID: 1\n",
      "电影 title: Toy Story\n",
      "ID为1 的电影数据是： {'mov_id': 1, 'title': [1, 2], 'years': 1995}\n"
     ]
    }
   ],
   "source": [
    "# 用于记录电影title每个单词对应哪个序号\n",
    "movie_titles = {}\n",
    "#记录电影名字包含的单词最大数量\n",
    "max_title_length = 0\n",
    "# 对不同的单词从1 开始计数\n",
    "t_count = 1\n",
    "# 按行读取数据并处理\n",
    "for item in data:\n",
    "    item = item.strip().split(\"::\")\n",
    "    # 1. 获得电影的ID信息\n",
    "    v_id = item[0]\n",
    "    v_title = item[1][:-7] # 去掉title中年份数据\n",
    "    v_year = item[1][-5:-1]\n",
    "    titles = v_title.split()\n",
    "    # 获得title最大长度\n",
    "    max_title_length = max((max_title_length, len(titles)))\n",
    "    \n",
    "    # 2. 统计电影名字的单词，并给每个单词一个序号，放在movie_titles中\n",
    "    for t in titles:\n",
    "        if t not in movie_titles:\n",
    "            movie_titles[t] = t_count\n",
    "            t_count += 1\n",
    "            \n",
    "    v_tit = [movie_titles[k] for k in titles]\n",
    "    # 保存电影ID数据和title数据到字典中\n",
    "    movie_info[v_id] = {'mov_id': int(v_id),\n",
    "                        'title': v_tit,\n",
    "                        'years': int(v_year)}\n",
    "    \n",
    "print(\"最大电影title长度是：\",  max_title_length)\n",
    "ID = 1\n",
    "# 读取第一条数据，并打印\n",
    "item = data[0]\n",
    "item = item.strip().split(\"::\")\n",
    "print(\"电影 ID:\", item[0])\n",
    "print(\"电影 title:\", item[1][:-7])\n",
    "print(\"ID为1 的电影数据是：\", movie_info['1'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "考虑到年份对衡量两个电影的相似度没有很大的影响，后续神经网络处理时，并不使用年份数据。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### 3. 统计电影类别的单词，并给每个单词一个数字序号\n",
    "\n",
    "参考处理电影名字的方法处理电影类别，给不同类别的单词不同数字序号。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "电影类别数量最多是： 6\n",
      "电影 ID: 1\n",
      "电影种类 category: ['Animation', \"Children's\", 'Comedy']\n",
      "ID为1 的电影数据是： {'mov_id': 1, 'category': [1, 2, 3]}\n"
     ]
    }
   ],
   "source": [
    "# 用于记录电影类别每个单词对应哪个序号\n",
    "movie_titles, movie_cat = {}, {}\n",
    "max_title_length = 0\n",
    "max_cat_length = 0\n",
    "\n",
    "t_count, c_count = 1, 1\n",
    "# 按行读取数据并处理\n",
    "for item in data:\n",
    "    item = item.strip().split(\"::\")\n",
    "    # 1. 获得电影的ID信息\n",
    "    v_id = item[0]\n",
    "    cats = item[2].split('|')\n",
    "\n",
    "    # 获得电影类别数量的最大长度\n",
    "    max_cat_length = max((max_cat_length, len(cats)))\n",
    "            \n",
    "    v_cat = item[2].split('|')\n",
    "    # 3. 统计电影类别单词，并给每个单词一个序号，放在movie_cat中\n",
    "    for cat in cats:\n",
    "        if cat not in movie_cat:\n",
    "            movie_cat[cat] = c_count\n",
    "            c_count += 1\n",
    "    v_cat = [movie_cat[k] for k in v_cat]\n",
    "    \n",
    "    # 保存电影ID数据和title数据到字典中\n",
    "    movie_info[v_id] = {'mov_id': int(v_id),\n",
    "                        'category': v_cat}\n",
    "    \n",
    "print(\"电影类别数量最多是：\",  max_cat_length)\n",
    "ID = 1\n",
    "# 读取第一条数据，并打印\n",
    "item = data[0]\n",
    "item = item.strip().split(\"::\")\n",
    "print(\"电影 ID:\", item[0])\n",
    "print(\"电影种类 category:\", item[2].split('|'))\n",
    "print(\"ID为1 的电影数据是：\", movie_info['1'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "### 4. 电影类别和电影名称定长填充，并保存所有电影数据到字典中\n",
    "\n",
    "在保存电影数据到字典前，值得注意的是，由于每个电影名字和类别的单词数量不一样，转换成数字表示时，还需要通过补0将其补全成固定数据长度。原因是这些数据作为神经网络的输入，其维度影响了第一层网络的权重维度初始化，这要求输入数据的维度是定长的，而不是变长的，所以通过补0使其变为定长输入。补0并不会影响神经网络运算的最终结果。 \n",
    "\n",
    "从上面两小节我们已知：最大电影名字长度是15，最大电影类别长度是6，15和6分别表示电影名字、种类包含的最多单词数量。因此我们通过补0使电影名字的列表长度为15，使电影种类的列表长度补齐为6。实现如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "电影数据数量： 3883\n",
      "原始的电影ID为 2 的数据是： 2::Jumanji (1995)::Adventure|Children's|Fantasy\n",
      "\n",
      "电影ID为 2 的转换后数据是： {'mov_id': 2, 'title': [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'category': [4, 2, 5, 0, 0, 0], 'years': 1995}\n"
     ]
    }
   ],
   "source": [
    "# 建立三个字典，分别存放电影ID、名字和类别\n",
    "movie_info, movie_titles, movie_cat = {}, {}, {}\n",
    "# 对电影名字、类别中不同的单词从 1 开始标号\n",
    "t_count, c_count = 1, 1\n",
    "\n",
    "count_tit = {}\n",
    "# 按行读取数据并处理\n",
    "for item in data:\n",
    "    item = item.strip().split(\"::\")\n",
    "    # 1. 获得电影的ID信息\n",
    "    v_id = item[0]\n",
    "    v_title = item[1][:-7] # 去掉title中年份数据\n",
    "    cats = item[2].split('|')\n",
    "    v_year = item[1][-5:-1]\n",
    "\n",
    "    titles = v_title.split()\n",
    "    # 2. 统计电影名字的单词，并给每个单词一个序号，放在movie_titles中\n",
    "    for t in titles:\n",
    "        if t not in movie_titles:\n",
    "            movie_titles[t] = t_count\n",
    "            t_count += 1\n",
    "    # 3. 统计电影类别单词，并给每个单词一个序号，放在movie_cat中\n",
    "    for cat in cats:\n",
    "        if cat not in movie_cat:\n",
    "            movie_cat[cat] = c_count\n",
    "            c_count += 1\n",
    "    # 补0使电影名称对应的列表长度为15\n",
    "    v_tit = [movie_titles[k] for k in titles]\n",
    "    while len(v_tit)<15:\n",
    "        v_tit.append(0)\n",
    "    # 补0使电影种类对应的列表长度为6\n",
    "    v_cat = [movie_cat[k] for k in cats]\n",
    "    while len(v_cat)<6:\n",
    "        v_cat.append(0)\n",
    "    # 4. 保存电影数据到movie_info中\n",
    "    movie_info[v_id] = {'mov_id': int(v_id),\n",
    "                        'title': v_tit,\n",
    "                        'category': v_cat,\n",
    "                        'years': int(v_year)}\n",
    "    \n",
    "print(\"电影数据数量：\", len(movie_info))\n",
    "ID = 2\n",
    "print(\"原始的电影ID为 {} 的数据是：\".format(ID), data[ID-1])\n",
    "print(\"电影ID为 {} 的转换后数据是：\".format(ID), movie_info[str(ID)])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "\n",
    "完整的电影数据处理代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "电影数量： 3883\n",
      "原始的电影ID为 1 的数据是： 1::Toy Story (1995)::Animation|Children's|Comedy\n",
      "\n",
      "电影ID为 1 的转换后数据是： {'mov_id': 1, 'title': [1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'category': [1, 2, 3, 0, 0, 0], 'years': 1995}\n",
      "电影种类对应序号：'Animation':1 'Children's':2 'Comedy':3\n",
      "电影名称对应序号：'The':26 'Story':2 \n"
     ]
    }
   ],
   "source": [
    "def get_movie_info(path):\n",
    "    # 打开文件，编码方式选择ISO-8859-1，读取所有数据到data中 \n",
    "    with open(path, 'r', encoding=\"ISO-8859-1\") as f:\n",
    "        data = f.readlines()\n",
    "    # 建立三个字典，分别用户存放电影所有信息，电影的名字信息、类别信息\n",
    "    movie_info, movie_titles, movie_cat = {}, {}, {}\n",
    "    # 对电影名字、类别中不同的单词计数\n",
    "    t_count, c_count = 1, 1\n",
    "    # 初始化电影名字和种类的列表\n",
    "    titles = []\n",
    "    cats = []\n",
    "    count_tit = {}\n",
    "    # 按行读取数据并处理\n",
    "    for item in data:\n",
    "        item = item.strip().split(\"::\")\n",
    "        v_id = item[0]\n",
    "        v_title = item[1][:-7]\n",
    "        cats = item[2].split('|')\n",
    "        v_year = item[1][-5:-1]\n",
    "\n",
    "        titles = v_title.split()\n",
    "        # 统计电影名字的单词，并给每个单词一个序号，放在movie_titles中\n",
    "        for t in titles:\n",
    "            if t not in movie_titles:\n",
    "                movie_titles[t] = t_count\n",
    "                t_count += 1\n",
    "        # 统计电影类别单词，并给每个单词一个序号，放在movie_cat中\n",
    "        for cat in cats:\n",
    "            if cat not in movie_cat:\n",
    "                movie_cat[cat] = c_count\n",
    "                c_count += 1\n",
    "        # 补0使电影名称对应的列表长度为15\n",
    "        v_tit = [movie_titles[k] for k in titles]\n",
    "        while len(v_tit)<15:\n",
    "            v_tit.append(0)\n",
    "        # 补0使电影种类对应的列表长度为6\n",
    "        v_cat = [movie_cat[k] for k in cats]\n",
    "        while len(v_cat)<6:\n",
    "            v_cat.append(0)\n",
    "        # 保存电影数据到movie_info中\n",
    "        movie_info[v_id] = {'mov_id': int(v_id),\n",
    "                            'title': v_tit,\n",
    "                            'category': v_cat,\n",
    "                            'years': int(v_year)}\n",
    "    return movie_info, movie_cat, movie_titles\n",
    "\n",
    "\n",
    "movie_info_path = \"./work/ml-1m/movies.dat\"\n",
    "movie_info, movie_cat, movie_titles = get_movie_info(movie_info_path)\n",
    "print(\"电影数量：\", len(movie_info))\n",
    "ID = 1\n",
    "print(\"原始的电影ID为 {} 的数据是：\".format(ID), data[ID-1])\n",
    "print(\"电影ID为 {} 的转换后数据是：\".format(ID), movie_info[str(ID)])\n",
    "\n",
    "print(\"电影种类对应序号：'Animation':{} 'Children's':{} 'Comedy':{}\".format(movie_cat['Animation'], \n",
    "                                                                   movie_cat[\"Children's\"], \n",
    "                                                                   movie_cat['Comedy']))\n",
    "print(\"电影名称对应序号：'The':{} 'Story':{} \".format(movie_titles['The'], movie_titles['Story']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "从上面的结果来看，ml-1m数据集中一共有3883个不同的电影，每个电影信息包含电影ID、电影名称、电影类别，均已处理成数字形式。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 评分数据处理\n",
    "\n",
    "有了用户数据和电影数据后，还需要获得用户对电影的评分数据，ml-1m数据集的评分数据在ratings.dat文件中。评分数据格式为UserID::MovieID::Rating::Timestamp，如下图。\n",
    "<br></br>\n",
    "<img src=\"https://ai-studio-static-online.cdn.bcebos.com/e4b916b3d3bb48cdb00ab685817268ecd5f183f9e0564c6296b64ec346e1711b\" width=\"500\" >\n",
    "\n",
    "这份数据很容易理解，如1::1193::5::978300760 表示ID为1的用户对电影ID为1193的评分是5。\n",
    "\n",
    "> <font size=2>978300760表示Timestamp数据，是标注数据时记录的时间信息，对当前任务来说是没有作用的数据，可以忽略这部分信息。</font>\n",
    "\n",
    "接下来，读取评分文件里的数据："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1::1193::5::978300760\n",
      "\n",
      "评分数据条数： 1000209\n",
      "用户ID： 1\n",
      "电影ID： 1193\n",
      "用户对电影的评分： 5\n"
     ]
    }
   ],
   "source": [
    "use_poster = False\n",
    "if use_poster:\n",
    "    rating_path = \"./work/ml-1m/new_rating.txt\"\n",
    "else:\n",
    "    rating_path = \"./work/ml-1m/ratings.dat\"\n",
    "# 打开文件，读取所有行到data中\n",
    "with open(rating_path, 'r') as f:\n",
    "    data = f.readlines()\n",
    "# 打印data的数据长度，以及第一条数据中的用户ID、电影ID和评分信息   \n",
    "item = data[0]\n",
    "\n",
    "print(item)\n",
    "\n",
    "item = item.strip().split(\"::\")\n",
    "usr_id,movie_id,score = item[0],item[1],item[2]\n",
    "print(\"评分数据条数：\", len(data))\n",
    "print(\"用户ID：\", usr_id)\n",
    "print(\"电影ID：\", movie_id)\n",
    "print(\"用户对电影的评分：\", score)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "从以上统计结果来看，一共有1000209条评分数据。电影评分数据不包含文本信息，可以将数据直接存到字典中。\n",
    "\n",
    "下面我们将评分数据封装到get_rating_info()函数中，并返回评分数据的信息。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ID为1的用户一共评价了53个电影\n"
     ]
    }
   ],
   "source": [
    "def get_rating_info(path):\n",
    "    # 打开文件，读取所有行到data中\n",
    "    with open(path, 'r') as f:\n",
    "        data = f.readlines()\n",
    "    # 创建一个字典\n",
    "    rating_info = {}\n",
    "    for item in data:\n",
    "        item = item.strip().split(\"::\")\n",
    "        # 处理每行数据，分别得到用户ID，电影ID，和评分\n",
    "        usr_id,movie_id,score = item[0],item[1],item[2]\n",
    "        if usr_id not in rating_info.keys():\n",
    "            rating_info[usr_id] = {movie_id:float(score)}\n",
    "        else:\n",
    "            rating_info[usr_id][movie_id] = float(score)\n",
    "    return rating_info\n",
    "\n",
    "# 获得评分数据\n",
    "#rating_path = \"./work/ml-1m/ratings.dat\"\n",
    "rating_info = get_rating_info(rating_path)\n",
    "print(\"ID为1的用户一共评价了{}个电影\".format(len(rating_info['1'])))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 海报图像读取\n",
    "\n",
    "在电影海报的数据文件夹下，海报的图片文件以\"mov_id\" + 电影ID + \".jpg\"的方式命名。因此，我们可以用电影ID去索引对应的海报图像。\n",
    "\n",
    "海报图像展示如下：\n",
    "\n",
    "![](https://ai-studio-static-online.cdn.bcebos.com/5085b69aef05498bb526aaf8c3d931d0e955ab066d5043478612284fee9b66ca)\n",
    "\n",
    "\n",
    "图2： 电影ID-2296的海报\n",
    "\n",
    "![](https://ai-studio-static-online.cdn.bcebos.com/4a1bb54764b54ac69ad0d7df5263621f045ee2de6a7141e5be5018f8c843f710)\n",
    "\n",
    "\n",
    "图3： 电影ID-2291的海报\n",
    "\n",
    "\n",
    "\n",
    "我们可以从新的评分数据文件 new_rating.txt（注意部分原rating数据中的电影由于获取不到海报图片，所以进行了过滤处理）中获取到电影ID，进而索引到图像，实现如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAALgAAAEICAYAAADsjj4GAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzsvXe8XUd57/2dmdV236eqHfXiItuSuw3YuGFsE9Ob6bwBkhDSyH15SQj3woWUmxtIQqgG0wIYEwzCxmAccMe9SLJlSVY5qqeXfXZdbWbeP9aWULgYy0m4EXz002d9zl5rZs2amfWbZz3zPM+MhLWW4ziO31TI/+oKHMdx/CpxnODH8RuN4wQ/jt9oHCf4cfxG4zjBj+M3GscJfhy/0ThO8GMAQogfCiHe+kvSvyyE+Oj/zTr9puA4wbv4rySRtfZKa+1XuvV4mxDi3n9vWUKIZUIIK4RwuudfFkLEQohG93hSCPHXQojKLynjrUKIR4UQdSHEASHE3x4qr5v+NSHEaDf9aSHEO37B85tHHB88Iv1QfY5MV//e9j4bjhP8PwlHEuAYxN9aa0vAAPB24Dzgp0KIwjPkzwN/DPQD5wKXAv/tiPS/BpZZa8vAS4GPCiHO/LkyqtbaYvf4yC+oT/GIQ//HmvfM+LUkuBBijxDiz4QQTwkhZoUQXxJCBEekv1MIsVMIMSOEuEkIsbB7XQgh/l4IMdGVPk8IIU4RQrwLeCPwvq5Eubmbf6EQ4kYhxKQQYlgI8YdHPONDQohvd6VZHXjbz9VxuRCiJoSQ3fPPCyEmjkj/ZyHEH3d/3ymEeIcQ4iTgs8D53XrUjiiyRwhxS1cKPyiEWPlc+81aG1prHyYjZR8Z2X9Rvs9Ya++x1sbW2oPA14HnH5G+xVobHTrtHs+5Pv838GtJ8C7eCLyYrGPXAH8BIIS4hEzCvBZYAOwFvtm953Lgwm7+SjfPtLX2WrKXeEiyXN0l5s3AJmARmRT7YyHEi4+ow8uAbwPV7v2HYa0dBurA6d1LFwLNLokBXgjc9XP3bAV+F7i/W4/qEcmvBz4M9AA7gb886p76OVhrG8C/Ahcc5S0XAluOvCCE+LQQog1sA0aBH/zcPXu76s2XhBD9P5f27q7weVQI8ap/RxOOGr/OBP+ktXa/tXaG7GVf073+RuCL1trHulLmz8gk4jIgAUrAiYCw1m611o4+Q/lnAwPW2v/ZlWS7gc+TEe0Q7rfWbrDWGmtt5xeUcRfwQiHE/O75t7vny4Ey2eA5WnzXWvuQtTYlG0zrn8O9vwgjQO+zZRJC/D/AWcDfHXndWvtusr68APgOcEiiT5H13VLgzG6eIwf/J4DVwCDwQeDLQojn8yvCrzPB9x/xey+wsPt7YfccAGttE5gGFllrbwc+CXwKmBBCXCuEKD9D+UuBhV01o9ZVF/4cmPcMdfhFuAu4iEwC3g3cSSa5XwjcY601z9bIIzB2xO82UHwO9/4iLAJmflkGIcTLyb6GV1prp34+3VqrrbX3AkPA73WvNa21j1hrU2vtOPAe4HIhRKmb/pi1drqb/gMy8r/yP9iWZ8SvM8EXH/F7CZlEovt36aGE7kSqDzgIYK39hLX2TOBkMlXl/+1m/fmwyv3AsLW2esRRstZedUSeZwvFvItMwl3U/X0vmS77f6gnz6HM/zCEEEXgMuCeX5LnCrIv1tXW2ieepUiHZ9bBD7XnmbhmAfEs5f+78etM8N8XQgwJIXqBDwA3dK9fD7xdCLFeCOEDfwU8aK3dI4Q4WwhxrhDCBVpACBySouPAiiPKfwhoCCH+PyFETgihuhPSs4+2gtbaHUAHeBNwl7W23n3Oq3hmgo8DQ0II72ifc7QQQvhda8cGYBb40jPku4RMsr7KWvvQz6UNCiFeL4QodvvkxWTq4U+66ecKIU4QQkghRB+ZSnKntXaum/7q7r1SCHE5Wd/c9J/d1kP4dSb4N4DbgN3ALuCjANbaH5PpdjeSTX5W8jO9uUwmlWbJ1Jhp4H93064DTu6qIxu6pqvfItN1h8l0yy+QTU6fC+4im8juP+JcAI89Q/7bySZ0Y0KI/0Mt+HfifUKIBll7vwo8CjzPWtt6hvwfJGvnD46wVf+wm2bJ1JEDZP34d8AfW2sPkXQFcCvQAJ4k082vOaLsPyL7mtbI+v6d1to7/1Na+Qsgfh0XPAgh9gDv6JL5OI7jGfHrLMGP4zieFccJfhy/0fiVEVwIcYUQYnvXo/j+/8yyrbXLjqsnx3E0+JXo4N3gmaeBF5FNRh4GrrHWPvWf/rDjOI5fgl9VgNA5wM6u9w8hxDfJ3Nq/kOD5omfLfXmM1iilsEJgrQEhMNYgpAQEruNircVi0FojhECIn5lQhZTQHbDWWoSUGK1xXZfUaJSUgMUai7AWIUDKLJBNGw1CIBDY7j8pJQiJTixCCCSSVGukkiBAyayeUsmsXtZitEFKh7AdIaVESonjKJQr0To9HLihlMSkGmstCJBCIgSHy5FSYqxBSok1WR9oYxAIhJAkUYrrORhz6PkaRNb8QzLLWosAUqMRUmZt6LZXADrViOzxKCcrS1uDMRrHkWBBSgeTGqw1OI7CGIuxYLEoR6J1ghIOxmT9qbvvMHs3kKYpXQ5kbcEiuxWVQqG1ydrlZGlgUEJhrcX1fJIk5UghbLsNnBienbLWDjwbEX9VBF/Ev/XyHSCLSjuMboDTuwDKfTne8sEXEuuUXC5HGEekGPxcwNjkBPligUK+SBzHmNTi5iWu65IkCQBBkMVZdTodPM8jCALiOD7cqdPT07glj2qhhDQWaTQiScnn82AsnSjEK+bpxBGJMSTW4PmCVquDkh45r4c0hKiTUG93qPSUsVbT11cgTSOEAmNT4jDCISCJoTmbELY6BDmXcjmPcWL6BntwPI8wjpip1XGMptVqUSqV0Dojle/7aJ0wOzvL/AWDtFotHMeh3W4RFIso6RN1UiqFXkZHR/EDl1K1yGx9DKUUlUoFnSq0FcRxQmdmDusqYqvpnz+PuUadvOfjK5dqscTu7TvI5XIAeIFP6vnMTI9RCCQ5r0gaCtLUUio5zE5P4Xg+jlfBYIhNizBpkKeA53lAd3AqMMaglAIMcRzjeQ5aazqdDm7OIef4hHMxOrXkqxXqpg0Ycq6Dk1oqlR5m6w3CxBD4ZeI4JoljhLAopfjkG7+1l6PAf9kk01p7rbX2LGvtWW7Rpe5DUnYYT+uMhzXiNGV4117OX3ceLz7/MkZ3DRPWZgm8FJto5qZnGdl3AB0l6CjBQWITjTRQm5qhNjWDsoJmrU4axuioQ9Jpk7RDxvaPcuKKUxgdnqA+02HV8pNxVIHp2TaTM3U62mJDsG0N7QghY2xB03aa+K6hNjLC9MgojUaDRKeEzRaNyRl0M6HdaNJu1OkkswyPbmeqeZB6NA2EHNi9k9rIKLPDYzT2TjA0fzFpqPFVQNxOqM80qU3VaddDFgwsYnp8FgePTiOi4Bexs5pwpkEat2naWYIej7nmHCN7RyjICjJSzI7N0pyao8cpcPbq03nhaZcSHowZZJCpLeOUGx6d3bOo6YSdD21lfqmPdq2J4zjMtZqMbBtjZn8dHeVozGgO7pnG1QG1mRrWE7RtzHSrSZwKoprBzjm4wmf/8EEGegYZOzBO2IyoTc1BKpibbpB0NDqy1KbquMJHtwOadcFkrc5MZ47p5hQuElqazsEGlbTI9O5x4nYIbkJqU1KbEumYOE1IdHzUPPtVEfwg/9aVPtS99osroST4ihiDV8hR6ell3/Aol5x3Ka+7+BouX3sF84sL0E1N0tDYFtgW9OcHcGKXZC4lrWtKqkxjvEmeAkVZIq1raAtKqgzaEngF6tMNFvQMsWbxiRREmd2b9nLGCedQ9fqRoUPBKSNjl/ZkQpEy/cEAcSui0Wjg+B4yEciOIYgcmjMhjak2OXK4sSQvC6xcsILmVIOFAwvQnYieQoX2XANfu1S8KrQMudTnlZe+lIvPuYRTlp9KY6wJbah6PRREHtqCaDam6vbQmmgjOuAmHkHoMz8/QNrOXvDc3Bz9lQEqbhU9o+kN+qh6FUw95RUXv5zL11zGsqUrUMJlamyS0044lSUDi7nk/IugaThn7RmsW30ag8UB2lNtApFned9SBoJ+TMOyYsEqls9bTmuiSXNqloIX0A47CCuZHZ2mKPIs6xlix6adnHPK2bz2stehIodwOsJPA0zTsLhvCbQt48MTDPUuJq4lVKIyg/RRsWWqsgc/CpjcNcG5a87mmqvexBUXvpRTTzgTTxZItKAddjDY7AtjU9pReNRE/FWpKA8Dq7tRcwfJPIlveKbMWmt0khIUPNI40wsX9QyxbsWZ6FCwc+8eLj3nSmZaU5R6C2x7aie2YFm3bh2LFy/mvvvuY9u2baxatZQL119EX18fAJOTkwwNDZEkCd+4++sMb99Lb6GXV7zkNayoLudNL3s71157LXpGctbqs3neuhdQ6zT4yvX/zKXnXMQ5p6+jlPP41I2fZ6I+Sbm/SEHleNnlV7JqzYlsGRvmwMFh1q5agW62WLB4Gbfe9iMuOvcSLrzwAi446wK+9tUv43kO73r97xLgsXPnLhpTTS5dewlt4PLzXsw3dn+DNSes4SUvvJLx9jibN2/i7rvv5k1vegPj4+OceuqpzM7OsnZgNSPNEdKi4W++/Pf0lvoZ3z3B+lVn8PaXvYk2c9xx/0+YYpqKqZDECRu3bARpGBkd5QN/8ufcftdtnHbCqTgRPO+880mNZsm8lXz7pg286KKrOHvBWcyYGf7pC59k/ar1nPLitXzzm//MRS95JUEp4Ou3fZcH79vBZedezDVXvgwvtSybt4oLL7yQXnr50Hs/zOc+9zlygc/ll17OqUvXcv9T9/P973+fV172Knbv3s2y8ipOOGE1DpKb7tzANzd8i0//w6fY+MRGzl1xHhaJyhd44OmnaLgp6Bjf9/FdD20NSZocNRF/JQS31qZCiPcAPwIUWfjqlmfK70iFbbUxIoDEUJ9sszRYzaLccubJpTyxbSdXX/0G6qbOnQ/fwZBjecsb3sLw/mH+5Sv/wvve+z42Lt9IvV5H1zRfve4G3v/+9/PD79/O9PImb3nDW5i8uMHXPvvPPPnUDh5a+CRydY5PffzTTE/OkJsrcNftt9Fo13jrO97O71z525x54oX84ObvsHf3Vt75R+/mE9/6InO1Dq9/0TWsX7qer173VW586HbWrz+FN77wfCpC8Tef+3tOOOEkrrrwKj735S/wmte8hnV/cgYf+7u/41Mf/BKvf/VrOH/dZfzl1/47l591FWnY4ZP/4zO87W1v4YxTz+DaL13LwkULePXlr6HQKrJ+4elsq2/jh1+5leHhYf72zz9Gbm6WG39wI3mZ5/F7NvHWl7+D1130el5+5dWcdf46PvTfP8D3NmygN+qlNdVkPDmIqWic1OUDn/ogoztGefDhRxkbHmFB3zIeuP1B7rnnp1xy6YuoNvq4+rWXcs4F5/KOP3k3//t/fYzFf/AnvPmq1xCUmlx/1/Uc2LWL0eF9LLiojyH6iDpzbPj8TRTaJV7xW6/gta97LWeeeSbv/4M/Z2RkhPe864/4zGc+wwm9J7O4bxEn9a3lb677X2z4seE1L3k1L7vo1fSUBvjOTTfw0KMPccuPNtDTP4/R2jSlhT0YK2m3m2idEFpNvphDiPxRc/FXpoNba39grV1jrV1prf2lwfkCixIShUAnKa5y+PFPbmNqaoooSdi6YzuxTZhr17npBzd3qy1xHI/JyWlA4vs5fD9Hvd5kenqWcrnK/v0HAUk7Dinkc7ieIlcoZFYFJTl13TpWrFyJwdJs1Zmp1ahWy1g0GsFJJ60ll8vzyKOPEIYxcXxI97OsWLGC+fMWIqVDTuTZum0bP777TiZrU1gkjnD5xle+yfe+/X0GKgt55cteR7nUT5LEjEyNg5NZPk4++cTD5c5fMI8gCAhNiBACF5ddu3axbds2Wu0G3/3a15i3aAmve+3riKIIISz1eh2Ak046iUIxe/EbNz4Gnoe1ltGpEaxvWLxqMX0LBznx9FNopG1CYZA5j+UrV3HSiWtxVUBvsZeTTj6B1atXUizl2bHjaTZv3kilXGF0bpQnn3wSgJUrV3LTTRv4nT/8HeI45vIrryAo5GnpFs+/4AKanSau8OmfN8jiZUvxVQ4jDCEx+0cPsrW9jVFngq/edAMxlvVnns7w5C68AYmpRLTcGoVBl04yByYLMzfGkCQJURQd8R6eHceEJ9NacNzM5GTQeDmFU1B0RBunIIm9EK0SnLLE6ZHcsOF6JlpjLFgwj7/6649SS2Z4aNMDbN29hYgOER1m29MkMmKmNYXnOVgigryD9FL2HNzBCSeu4fXveD1nXXwGaZCSG8iRBinCEWy47Xs0bYNcb8CqU1eT7ylQ7MlhlObH9/wr9XCGF1z8Al55zcsZGOonJiLozaP9lEe3PMoU0yxaMcTyNSs4Ye3JXHjJxdz70EP86713YF1FaUGZqXSGcqnA6976ajY//ThjrYNcdcWLecGF51PrTLNp22PU7SzajVm8eiH9i/pYetISZlujCCBX8rCO5bY7fkiHJn/58Q/zp+/9Y2btNE3dBBVh8waFwFpLohM6JiJ1QeQ9rA9P7NrOZZe9iDe/482kIqLQU+CTn/ssb3r723jg8Qcp9Ba49p+/REzMTx9+AOMqpCMoVYq86w9+l7e/+x1MNqdp6wa7D+7AKM1LX/sS+hb2cvfGO5CO5S/+/M+Y1VN879YNKEDkDM4CQTvX5J7H7+Wn2x7IJtIixBYSkkJI5LaIaJGIEEEKJsXYFItGIlDi6KNrjw2CYxGOIjEajUblHXJ9HttGn2C4uZ0wN8fGsUfYNbOVwnyPltvk41/8GI8dfJRRPcKmvRv51m038PTEdjp+G2/Q5Yn9mwnm+8yJGrtbuxjes41qf4He+UX2Tw6zP9pNx6szmU6w+eBG4lLErJrhwYMPsmN6B//05Y+xdeRJTjn/JCYaI0zVx/BLgh8/cBtf3fAlHhy+nzZzTLXHeHD3/eye2sXqM1fx6M5H+eg/fojzLjiHNWes4dZ7b+UL37yO81/0PIZOWsr26Z3snNnDdd++jk3jm6jZGvdsvptPf/1TPLDnAfa2hrnhR9dzzxN3sW30KQ4293OgsY+Nw4/Rt6aHA/W9PDn+JEHJ58T1q3n6wFP84f/4fcajg+zp7OJ7d3yXaTPFI7seZCQcRVmJMJIkSUnTFKssXsljdG6C+zfdyzTTHGyO8L07NrBp16PsmNvDlolt3PHQncxbuYDywgoGxfDoAfAUTj5g2/DTbN2zHacnQPZ67K3t5kcP/IDrb/0adWbZPbWDf/jix9lwz3fYFw9z5+M/4dGdD3Hf8D08PbYV5RuUa1m2ZCkDff2AIEpCVN5B5RTasaTCYH5uKbKwIAT/xvfxbDgmogkHllfsSz5wJk4gM3uwkMStBJNaSoUy5XKZ0cn9aDT983qpev1MTU0RhiEzMzP09/czNDREvV7H9306nQ5zc3PMnz8fYwxjY2O4uYhyuYrjeJk9th0jZWZ3FkoiHQflOjQ7LXp7e5neP4XRCb3VMpPNKdxyQKlYoShyzI7NgHJw8wXaYQdfSaSFtkjwPA+FwDE+YZgwdnAKnSqWLFlKoVRgy5ZNzB/qw9iUpF2nWCxmtmutSdNMDYqiDvPmzSNJY8IwJIoiqtUySSMhKOWYac7hVwtMT87SXxlg+5PbGFq0AKUySe27OUwC0jrERpBK0NKgXAdjLVKIzCyXJnSaLfKFAo7jMDY9ie4o+gerdJIWYTPmg+/5EPum9nDr7d8mFhGzjQbVnqXE7RiiCEca+hfOo1ar0em0cF0XY9OuDRyEsCRJgu+7dDodhBB4ToSIPH77ij9lzfyT+OK3P8/mmQcIel2k7yJskTiyJLHGYMHGaK0xxuBIiZRw7Vt+8Ki19qxn49YxsdWBEJk3zRFO5sEzKflSHpOkJKZDvZ3SP9BLGHbQiaHFDLgRi+b300lrlHo9Rqf20N/fz/T0GFJKgpKgk9YQQpCvKJSTo96cQ3kufb0DzHUaOMphcHCAWqOOFQlSgSMNndYcvQvy1OtzNPQcCxcPgpK0Wi1aNsapCHJBQKITAmlJ0whtLI5yGRzsY3JqnHxPCTdxGJs1BE7ARGOSqkroWdCP6yvanYhFSxcQhiHNsI7WaeaYcmGwb4AoDml2B0C5N8/U1BQDg1n+xGh6cyVEj6IxN8fAwn5SFZEvF3GNAzikYUqr0yIQJaS0CCFxlCRJYhwhcRQkaUylL08qDCJnSVsxnleipVukuk4nifnCdz5Df+8AjVadvoEelHRQjiIWKYkTIV1BTId22sAv+l0Bk5KaBCkzT3O70wQvj1f0UEpREC6tOOGWH9/M3aV72b5/K6ZqQAqsFTjaxQWEk5CYCCUcUiDtCmPxHGTyMUFwgMD1cHDQViOVwnVdYgxaW8Koje952ARajTamDIODg+zatYN8wWfvvl2sWbOGemMGqQxaJ/i+jyVBa0OxFJAmoH2BdBQoS1AIcD2HTtJGSEPO83GVgxv4BJ6PzFscv8TExARhp4W0EtdYcmUf5WTd5hmFUpnnNQoTorbm4N59lCp5WmEd1wvoWVDhwP4JhuYvp9lqoE2KtQFSKGq1GmDp7+8niiKazSaO49IJW8RxjLWaer1GGHrEcczY9Di5XIHenj6aUy2stcSdGOUJrDDUGrM4jkMSC4RyyJXzyEihdYy1FqU8TGpxlEUJjXAFfsHD6Ihm1CRWMXlPkM+5OKLEQJ/PyMG9uK5icHCQTrtBHEZUgl7ygUuKj+NlHuRyuYyUkk6nRaFQoFIpkyQJs7Vpenp6cBwHazWFQoFONINTdTk4OYZpjeMMSiIbkfM8bJpi4gQHlQ1MpUmTTJMWFqSwh8MNjgbHBMGFgELRIY41Slgc5ZGmhsAvkqYpnhugbYqRGi8v8P2AqakpisUCSRrR09NDux1SrfbSCWdwfUWz2aBSGiIOXbAuJa9JoUcT6oi51hTLqycwPT5KwSTkvBCnJFCexRWGnJnEFWcxE01y4ooB2rZBsxHjyQIF0UunXqfUE9AKxumoEHfQIYrbfOuDO2nNRqw7ZS1vfdMFxFGd5X3Libdvx5teSSeaxCnPEFW24QQhonYqOU/RmRllXv8AQSTx/AKdNAY3BRnjSoUnUirFEpMWRJTimJTZQNCIYiJtWEgFGQTErsUmMbm4jfYd4gIUZAMntiglcPwQx7OEoUeSFnFlBXSLnNG4KfjRQkzFIo3E9wtIJViyYgHaNNBAvlokMEWajWmkdPClh440+ZIFbTFJwmB+gDRKiccjrLX0F3oJ4zZR1MQvOhjdoJzvJfVSpMpUD60thbhE2hIoJbBBAyMExqYIo3FFHhLdnWiClUcvwo8NgiNQSiGlwdosfkQp0W28BgxSZQFP1kK7lX3+XM/D8zySJJuQdNoRXhDg+5I0TUl1B2SK5wp07JLqBo6n8K1iYmaSXD6H8hMc38X1XXyvjItLa0KxfdMoXk4wtGwQHSlklNJsGf7mY3/PvMFeznvBehaf1odbLDGwfCGLB8o0Dm5iZs8Ej4xHrF1Ypafs01Odz0O3Pcbj91xPsLSHy152Os9bupJ8QTCnXcJ2Ez/n005TvEKFqZk5CqUCrnIR0sdB4NoAKQMC0cHXEt9aZJSg4gRpDcJmX0DlCLQGRIyrPKyXw0lcsli1BJ2GgCXvB4TaIoXJ+lQoLBIrfSBECNsNFMsmc1I6pGmKMQaQCKEOB7plwWASDGgLidUkNsFiSXWKnzgkOsXgoGRwOABLa41Fd8sQ3aC0jI5ZoF1WN6UU2nD4ec91znhsEFzQJbjGWg5HoiVJQppmk0HlyMMEt0YhFDjKRSqDtSnWSNLUQGQQIhsMyk27AUwpM82UyLaxYUIhX0V6ithEpElEsaBQwseTVdKWz1e/cBPRtn5OP30ds9vH2LLlCVasWE1fdQGNrQ6NLdPsfex2+lflGFwyyNrTT2VoySLmqQWUBvqZnZzhUx+6gVIRli9ZztPbR1k0uJaDO7by2E2beefrP8js7Bi2MoFJmijhovI5TKKo9M8jjjoo6eMKg9Vg8cEG+CrGN+CaFCeKII7xrAVh6LTbCF/hGoOwknYnoZ0m+CYgTkLKRY+8X6TRnEOnbRxRQImuR1C4WeSlClAyxHUVrud0Ixs1UqquoDn0vgSHthMUKGziYLAYq+mYmFB3XenKYKzBGJMNCpPZ5o2MDpcnpTxcZkZw0yVxNsiEAJMoBBaszpbf26M3/h0TBEcAwnRHtsFxDDq1GJN1jkWTcwqAIdWaUrGIEBZj067DA5QLQmRSIUks+UKJqCNQMsDqHH55DD+t0lMeIGwZtBL0DpaIwyYrhlby/vd8gqcfnGZwyWIMRc7uWwM1n+9d/yNWLFrNZS96OT+45TbKegC8mFIhIG8U0Zjg6fv2sf/xaeKJiLAWUXb6MuvBbMhIpFlcORnf8ZGVZbSGZ3nnBR/B83wWXuXx2je+DF2doskUQW9AZ9aSRgLP5FHWJzUhCRHIkEQLMKCMRugY0hi35BP5Fukm6LRNmqTklUC5AuWCZysgY5K0TRynKOOQzwfEcSv7KkofjUvqSnQhpVrO47oKKSVJEqF1JkkLhRzGgDGglCGJNZBJeWOzSaW1Gp2mxKaD40hKpRIYSyINCpW9M6NxlAALQjkIFBpNMwrJ+R5SKlzXA5GF6BqbYpXCGoOSMhssz4FaxwbBu9A6QetM+hoDrut246UNUmajXVqJMW0cx8FVEqyLEAKtM2k/f0Efvu/jqByPPLAbz1FUK1VkoUHVnU841kSJEs16yn0Pb6TV7PCd0ft4+t5pBCVEp8DQ8n5279vGU7siWqZF32AfylWMTB4kVm3K/QGVoTzFeT6O66KUizGadjhHAhQKRTwd4IscrvJwyh6tzhxeUeIXe5gabzPXDDnw3YO0Rm/mf37xTUxHe2iZKXJFl1ArZGrQiYtVIpOEToiOiyTG0rGGSKfENiHvFzGuIjIJnidxPR9PSFzfJ++56FaeJEnRNsR1HESsmGvUCXyVCRXrYHGwIsU6CUrlEMIFMs/CAAAgAElEQVR248sNQh7qf/lvJCtksexCCISMQCeZJUwn+MbiC4WbZiGzsmsydD1wbBbnfkg1USqTxofLEgKpQAiJMWCNQKAQmO5fgXgO7ptjhuBHGu+zTyN4noexKaargylHYFGkaZp9vpA4ykU5ZJ2WGBxXY21Co5Fy1x2PYtMy1fJ8Lroc3FLI5IFx+qtLuffmzfz0nl3Z5gZCUnQGyZfyDBRLBJ7EXdjL5LZdtNKYRUuWkxjBdG2W8mCZ3IAiDjSpL8iXiiSRYXamxuzsLGEnJF/OsfLklaSJYe/e/cx05ijlBWmc0mp2EMqlkCsiYp8tt++FWsBA7yBJbRY3sDjaYuOEJM4WESgpMVIh8REiIY4SOkmHKDYUpYMjfaT0sDpFOg7VYh/GKsJUY0QVmSvSTmKUEvilErLjYE2CsRphHLTIwgasamGth9bi3+jAh8htjMFauqpDtnjCcRyEyLaXEdaitINEUlAByihc1wFtunp5AkpgE91d1NG9H3v4OdngskcINomQ9vCBNc9pm6BjguDZKhXbJXn2UoW0OK5EpQrbHfECkU2YjMJoka10ERbPd3BV5qhxXAnGwVE+mBw6cYlCwa7Ns+SWdig4HcqqyH237ILYJ+8sReLi2Sl8FePINhqPmfocpZ5eZFqgUOxneM8IB0cncYcgqOTxqy5WOlhc0jglbgtsZCkEeSqFgHWnrWXVqpOp15t89rOfpdHqgNVIR1Eul8G6qJpDYus8eed+TrtwiBUDpzMZ7aKdD0ncDlooHOEjZRFrSxjtkhhL21riOMWGEKQBvixk5WHp8UrM7mnwyIOP8sTGLZAf4F3vvZRyr0c9rJPGAuHkSaIW0jg4Oo9AgEgQ6J/pxurQvEgc/kJqbbBWZYPOyd6H67po6yKMRths1ZPC4qsiUoKrPKLEYlNDHGW2bmUNwmiUcnGERDkWz5G4qjvHSvVhDkhhkZbDh+3+PVocEwQ3NgukCXIecZSitcVxHKIowvNc8vkcxsYIkw2CODLkfA/lWHr6fCDFGEkut5htT4yzZ/deJsYb9FUXUC5XkVLSmhkgnLeDJcsNMtrM3374xXz76/vZ9GQTjxxuPsQvQkelOH4P5ZzDVG0WkaScue4UPvKRj9BKJzjv1NOYbB3E4jFYXkxYS5naOcrovnHecPFbueoVF7Ph5m/yr/9yMw/1PsIf/tF7WTG4jD37tuM5LiZOkCQIoeldFNLHfL7w0Vs5MLmPoGL5vY9czoUvWYfqjZDkaYwLvvLpm9n00H7mDRqGVi/h6te9FDF3AM/Lc8eND3Bg1yR7ntpPzg8I4wgRFiiJCiIqMskUm9cPc8HVJ1LXNQaWlKjNthBhjrCVkHfKxHFK2glZdcJKGjNNkuRnTpo0zZaMeZ6f2bKNYHa2QRwn2XI2G+OoPK4XEKcRs0kLqSC2URYH04lIwixgan6+n9nZWXIlRaQNOo0xSmVfYqlI4wQwKCfT7ZUUgEAKTeArfC+g0+kcXgZ3NDgmCG6tJU0TlPK6S7Y0aWq6OprKXNhJSD4f4Pseig6un+L7ilQ3gEwXbzctGx8ZYWR/EyUDhhb3kcspjA3Rgc9MQ5DaKrkCnHiWy1XhfPbuvx1HQFO7xHMx+TzkRAtHGKTQgKYZ19k9uo3+eVWE2yEoCUrVAMcKonqHsX0j9OR7OWP9mQw/vZNNj28k7kTZ0jDPI+x0wAiEEQjpYGyClBDLJjpW5HML6CsMMT03yj9+5Ifs2TXCVa+8hIGeKvff8hB3fWcT7UmYqcLj99R4+OG9vP3Nb+Zb37qFrZuG0Q1wtSJnfPJOno70cEWBnJ/H713Ag3c/zLmXrmJoaB67JnaB9HHcAEvM9FS2pWOhEHBg7wGU8LrmQBcpM8uIUhLXdbpzo8ymLpXA2jQTTmmHdqdDO27j5F2kEiRegvA8SA2e66JjjTYpxVIBrWcz6UzXUoPuzrEyk6RUAg6tu5UWa7M1uZnKJLvnR4djguA/Q7a4VloJGBwns79GUYg2EUmiEMKlp+ohJVSqAZ0wppAvoUSJkf1tJg5EOKafcrEH33GQRKRpRCcdo9kusmufYe1JC1GVUU5/YYnnbw+4+Vv7yBfX0Ki3mLdiIXFzBteWUTIgV5A8+sSmzOoy1E+tU6M4UMD3A8KGYWq0RiDLnH3a89gzOswNN15HSgvhFzh53VpmalO0OnNYkZIKiVQSbTtYaZhr1umtzKdZayMdQbXQS8o03/nsJrY8Mk5veR5bHn2azoSk6vZQmw0JBouMbRrnuqnrmRieptgzSNM0WFjpozk3hgRKg0tozUVYKamP1viDP3oVeTfPzPgepIpxHYdWvYYjXMp9Ver1OnEaE5kQHR9aLE2ml6MJAv/wHClbZG1QynYHQiZxHU+jrEU4BqvA8RWlSpFWbY6CHyAsmKRDq90icLuLuEX2zo3hcFxQttg6ySbGXYJr87OF5NqkWI5+U95jguBSZjbQrFGHVpU7NJtZ8FRPb4UwbNPptHEcRT5Xplis8tN7H0BSwPcNGx+/l5mpFpXqMny3AKQkuoVNI5rtWUwyh5FnsGt/m1bU4crL2uR6mvzj597JWWdv46uflvRVl+MYTR9NJtJRWpMzrFq5lhtv+j5LTzqBjm0yv1oBK7Chz9i2OdYvez5XvPlqhrfv5a+ufR+9fUVK5SpvuOZdDPQv5BOf/CdaYR2pbHfFeQ5NB+VIqu5STCppxHXyxYCSk+e0U85l88YnGXm4zu54lN7SENapoUVIj7eAogxIii5m1wGW5IrUOxF4gj5H87bLr2DpsgW87+vXIfoHmWg1GVSKL3/2X7hs6gJOv/gEli5cyc6de+g0YhYOLMDaOkaHJInFuBU81xCGIXGkKVdKeJ5EOYJUxxyyUfuB7K6ozxwvYdrBd33KXg+tccvo/gl2jm/HdV1OOX0lJ561AuOE7JnaSmnAJ5lpI4TCcVTXpq0RWOIoPDy4lJQomRkXXOmSpilJkuA6Aindo+bWMUHwQ58poDtTtyhHHN524dDEJwgCPN+hr2c5tdk2e3d1GN55gL6+PrRxWTB/CUkSYolwXZdcwUUojZdaSkEPUmhyBY+Z+iStuTxBIc/+3XV6Cn30lufIuYbe3CCnD13ERu9fEMkSli5bxOYtm8nl8jglB0yLar6KMoI1i4c4a+0pTO7Zx09uvhnHc8kXS6SJob9niJ/cdhc6MggtUDiYVOFID6l9fAvg0YliEC5hpGmHEbm8T0+pgO2kTM3U8V2Bly/SSjTFKEZ2WhDPcvWF53H7PQ/QkFAuFohmJpjYtpV5MqWvkGdUh5iwDW6F8X1zfP26W3jgsSe59BUv4InNO9i5dTcvuvRS1p0zj5zbIQpDtC3h0sDreoi11sSxIVAOnqsAhTEp1iqk5LDfQuHTX1qA6ATc9cO72PLIdmqjIcqDx+/YzMvf2OGsS06lUKwy15wmJzIVBDhsoTlkpclW42cWs0Or8pM0zcyWGJT6mYf1aHDMEDzb5+SQMyD7hOXz+W4j7eFtCer1Oh/58MdJY4WrquT9heS8KoPzK7h+zOTMLtrtBo70cbwecnmfYqmfoO3QjDWuJyEWTE3ELFi+irvv2MSGGzZyyUV/gZPOY+6g5un7J1h7xQpWLV1OpTrIdzY0wBSpFHMIJ8XqJnGrzUsuupp4ynDdV7/C6Nw41cEqEsWZZ5/Ppse28Mj9j+N7oJAoIUi1RGoJ2sVB4nk+SWKRAlzfRSrLyMgBBuf1Mrp3L6XAZ6Y2inYt+Z6AXBIyMTfBit4cr7n8Yt79rt/mQ5+/lu/e+TASmNy3h/3C4FpBozZHbmARFXJ0PJ+5+ji7Nu5H5jfR3zNIY9rhG5+4ka1XLOTci9bTsZqehX04aUIQ+EiVMjMzRbvToFTOsXLVki653cPu8kPCqLc8n6Lq4anNu/npzZvwbcC8YBGN9hy1PU2u++tb+MoNt/D3N7wHv+zT3Dt2uAwhLcKIbjCYOuzY45B+bg1xrA+TX3adPUeLY4PgWMIkRqRg4ha5nKLs+hSCPLV6A8cFfInWAXueTunM9uI4IW6+xunLLfOrCZVcHeUpnmoZto5pVK6MI10qtk1fyXCwWqTfjlEuBUzWDLtnzuOB+zvY8TVccuYl/N5bX4XNe0x1Ev70A3/D1I2LuOzKS3jJZVfx11/4DFNiGpXL0++W8MNB+tzFFJxVfOxrH2Gf3Ufs1XjZWS9n9+7dlPN5Hnvsxwh3ClwPJQRRFOHkHGJmcXwHAo/YStqNOgM5H0uHWn2Ohg4oDpaJi4JcYvBRlCtV5pptRpXB6RlkxvP58rXXcvH6Ch+4bC3uwQrf31GhJWdxTcJJwVpG6luZZYKJqJ8gcRGqF9cXDBSK5BAMyiptkWPmJ3nu3zRCYltc+IIBTn3pApYtWsU3vnQrt37/ARq1Jv39/bzhrWuYv6hKM6xxwrpT2DcxhkKxbfsu5OQsqq158qFJeswQXk6S6A6lShmvncfxXaaeOIjeEnDiuhMZWfhT9h8cReQUWlhkwcW3oEyCTGKkjHEcHys8kkRhhc1MwEKQJMlzikc5RhY85O1v/9N5mNTgKIlJNF46xIP3befprXvwcwEjowdZvnIltZmYExdqBuaVWTivSG/eIlOD5/h4fsBEmufBJ/cwOhGzdOFi+oqKvp48UWkUv2FZvmgNtabgxw/UOWnFeSyuruR5685h+cJ5KM/SbjdZtnAe2x6e4l3vfCcSwc0//AZBj+H6m7/EJz//j5x3xgWcfvIF/P4730dKgh9InEDwyit/i1arxfj4OMPDw1QqFer1etcSlOI4Dkplzg3HcZhrtLGppuA5JDqmFbcpzetlcHCQqbFxWhN1HOliLKQIbGwwjqavdwA7PILPLNUKLDnz+dx5YAdrVyicyVHGt85nRECzFCNTl1wakKYhfr9i9YUrCJwCm+59CqeVw7MuqBTpaTqtOUQpYXamQVR3KOZ6cZRPkiRo2wKZ0Oi0cIoOqQYvKBLHKZ6JUYlPXpXIe4rQNElMtgmT0DnCMMJ6UI9rnP3ik/nQP/w2E9MH6LhTTNammJmdo7cyiCMkVsdIGyKVA9YjSgztTnLYuRTHMcYYPv6a249qwcMxsWQtm1G72WoQbXGdAps37+Oh+3eyZ3sD3enFFWWiOUslqLB2+XyWz++jv1REYXGUIAgCisUqfT39DPb34OcMCZqZdsLIbMTI/jrnnPJiXrDuak5ZfCFlbwFzTY0slgmDArNGYfIFqv3z6DRb9KzIc8XLLyZOOtz53bto7O5wzSVv5oSFp1Dyeziw7wBu5nVi1YqV+NLlwIED7NixgyeeeIJyuczU1BS5XO7wpzWLklSHP7NhGHa3M8u2zkBKoijbgyUIgu5cJNsRSkqJYxOsSeikMTNUaLtLmbKLeXDbGCtOW84V11xBdeUgtaRFozVHUm/8LMxBHQpsMlir8XyVmeq69crny+RyJaJpQS6tMr+0iAJFREcQmICcKeCnRfqDeeR1hYrsw4sDiqKCsgU8J5/tXkWElQnKs2gZ4eUsxXKeTqcDGh796U4+9N8+SZ4FjOwdob+nl1UrVtNoxoDsbm0nMmeeMQirEaQIUqTQh4+jxTFBcKyk07QI6xDHBs8vsfGxHdTGQ5YuXY9N8szvmQ9pTCUv6CtVqPol8m6RQr6XICiDVXTaCaWcx6L5FeYNOEivzVy7zsGJacql9fzr957iW9fezdweQZDmGaz2s2BoAfiKN/7O73LVq97INzfcTKlSYN6CPBdcfB4micnrCtsf2Mvex8d53+99gHnlhXzjK1/HccGXkonxURzH4cCBA1hrWbRoEUIIisUizWYTONK9nXV5mqYIk02mjTGk3f+PKkkSms1m5kTpzqWyfRYtgavpKfmMTxzA7x9kbxKzq97C7e1l5UkL2bLzCZyeMhNJA01MbzHb0u5nz7UYk6JNilKCNI0O67ZRGJPEFlcHeASZNxFD3lP4qrvYwEpybkAgAnzhIhNwNeTdEjnPx1pNYiKstBhpQQpaURPlC6RwyBUGMTXFw7cM87pL38fKJctIwg4HDx5E4JCYQ256gdFg0kORiPawndxxslDqo8UxoYNjFO16FtYaBA65vM/sXJ2la1ZjQ0u5WMBV45x44gBnnrGaUlJEoDBKYEQbIbOtJlyVxWqsW93DwMAA+6YSJsZdpqctD9wdMHfnDl5x3nL27Bvj5edfQANDX1PxnQ1f48k774NKwDd7buYdb7qaIAS37bNuxTnErSIidRjZHbFy/QDv/d330idz/OH7/xRNSpgq+vr78fCo1+vdvQTbWGspFouHJfUhoh0icbEQ8P9T995Rkt3lnffn5nsrh85hekLPTE8OSjMaCQUQQoCQAIMwMsEkg3kB29hg8NrrvGCM8drGAa/JIOMlCY2EIkojjcJIkzWxezrnynXr5vt7/6jWrPbsnrVY3vcc+Tmnzq3uOvWrU+c+9bvPfZ5vUGQZL/CIhUCSFSSh0qi1UOI2f7LRamsTiigiUlUc2yWXSDBTfoZX37qbvdevJpFvcvX1KZLmTvSgyD/+1fv4T7/zV/zD338FzwzQVB2IUcWLHYsAP3DQDR0NMJMJ/MhvC58mTWRZwmlViUV48QepGDpICi3PBqUNjDOSOmHooJMminyi2EMyNKJIpeUqJJImmhlTqVfI5dPUawJDyiNJnbitSfq6MohqmXI9YrnpYFoKQglRIxUJFUmK0eWIQA1Q1PZ0WzPaIKyXG6+IHVySIGEBso2RhCBukEypqJogX0xgWgrr1gyycf1aHKeCkEEx1TZZ1rRQDRPdSGBaSaRIkDE1OtImhUySzmIHhXwXZ06MkTWSxC2HZCRgwacY5ohmA3JBAZQclGyefvJQu2HpweiRCXJmkUQyTbqQA0VmcXGR5clp3vMr72Lbxs1tQoLS5pJqmtY+CVq73Eqn0+1LM7xkUNJuh0VR1K5RJamNpZZASLTr0DAi8H1iCYIVrqYQgpYr0PUcgR1xyaXruPyqdYwtHmKqcohYmuLo4R+zXD6ElWjyp5//fa695kZiLyQMopWkkNuTQlnG8xyQYpp2rf2cGNPUiSSZlu8TyiCbGrKpgC7hiYhYkfDjGFnTiWVAFvihB8JDUyIMq41MlJQECStPFOv09Q8SS4Jmq0Y6kcAPWnhOi/f/2m3MzY0Shza9PXk6uwpIctQW11xpEWuy0t6xaatHqZKEJssrpeHLi1dGgssCIdkomodhxShqjGFKWEkZx61RLi9Sq9lcGJvEc2MSaYVCZwZZF6TSJrKioBo6imqSzeYhFvR29hC5MatXDWMaaeLKErpwiJ0KStCiPlfFnQ9Ienn2rLsSPbSQE0Ved90NSMDkszaHD56gr7OfIGyhJxSEKTg/M85Djz/OT+6+h+98+w7+5A/+jFatRdD0CYKAOI5X+JTi4s4NXFTC1XUd226zz0UU4AfuCqlDRZG1tiyyohP4bbhCMmlhmBqqJhMKHbsR4vsRO7duYezCDFOzDl7UQ7NusmpgIwMDWTxOYaVcPvsHnyGRTZHJZGi0bDTVAto7oOd5OE4L01IRBISRi+M28EKJCB2h6ARC4IYRfgxeBEGsIGkmnhsSBmDoSaANW1a1NosqCiEMBK4TEYVQKBQwTI0g9KlWq2TNNJrus33nOmTVI5mWsVsVbLuGbrTBXW2SBRdLEVVrD5tehO5K/9Eoa4IIM9X+Mgk9h650YTc9Yq9KxsyTKWaoNGpU6hVmF6rUS3UGBwcpFgusGhjAdlKEgYQiNCQhMPQsqbSORJkjR4/jhWnycoKiYRI065TLZeyyTKYiMbvk0jXQx73f/jayGTIzO8bH3/wJuuW17N62k1V9/eiJiFJzlDgjcd0tb0IzdPBDpk+Ms3HtLr715Tv4yj/8I2PVMxeBQL7fvuRrmkYcx2iahq7rF5Pfsixi34UoJFYkJCGQhUCmXcq4nodhmsiGShhEuM0GgZ+iFZboSoV0DbSYmahwyZ4PMrT+ao48f57h/iZGNMbg5qPYrs9V11/HF//qz/nN930aTVZoNBoocj/Li0soso6iqLQl0OM2wVeOUWO5TTSQZISkX2zJJY0EbssnncjgthpYqkptdplCPgVCxvVDQiFjJIw23NbzCMIWsuoxMNTD/MwyYcUi8sFX63z3ri/wG9deQ8WuoVspNDUEEaBIbdK5JHxiIREToUkr9w9h8L9owv978QpJcIkwgoHudTi2zPe+fxdxYJIr5NAUDaQA3TIJo4i64zI+V6PpSuSWyqRzWZKJDKqqo0gKuiQjqwoiFqSTCcJwClmBbLID4Usoage+SOCqEculMZbOP49+QuM69VUUChncWoNdfZvJ5Pvo7SyiKhFB7LJUX6S7t5/I0tEskE2VtSPDeE6AU6mzcXgzJx47jBBiBSPdPgkvnpAXReFfqlseRsFFil5b+r09FLLtFrre5jIGtkfaMjFNk2arTkda4dZf2snWS10WxAJnz+7nx/fsZ13PRp6W59mxscG+zdejqi2gxOvfeB2/a8rYrktKTqHrJq2W3x6qoawc25sMQkKWHAQxghCJmDZ/Rsa1m6iqjq5KeJGLZZqkOjK0mnU0I4+sGCgIoiBoD+1iD0OLaNo1JFVCM1ScOMQLInbeKPORT/4KtnsWVTeZnV0mjovtnZs2M2uF5oWQYjRNWbkZFhdRji83XhEJrsgyimqCyHDi6GlOHp5j28brKC8tE4VNghBy+QymmiQIFGquwC01WW7U6OyeoK93FelUgVwmhRS7SJKCHEtsWLuGheUqk/OL5Ds3Y481UM1ejEQR8iozk6c4M3+MpdIMpWCcnZt2sn3dZoY71qB1GahyiGEaTFfq1AKX3nSG8zNz5PNpVhVTaAnoH+rjyPwcVbvWFnd/SR3+4u73UsiB7/srEgrt6a2QQKzwG4UQKEhkU2lCEaPIEUHQ1uKrlpfJGrBxcy9vum0nl9xYYnCz4JEn53G9ObxWE99p0du7CxDIkg9BiWJnEdutYeoJXK9JHIHr+EhotP1wV6pU0QZXSZLT/uOiQXE7mQxTxVBVqpUFLE1ioLdAf38vBx5/FD8MkHQVSZHxPQ9JtKUp+vq7ELSRk7qlYztlJFRGdnez/YphDp4+i6kl8L0ylqWvoC0VZCWGOFqZWApUSQVF/rnY9C/GKyLBBQJZiVmYL3PwiWMoZJk4P0e+mEDTQNEjFE1G0jQUVcZDQiguQnYYnRjHdmOKOYegP2Kw0yRwfGIh01/oZsNQH4vzE6gdIe5YhJHuIte5hqlojkW7Rku2cTWHsxNnED4MZQfY3DNIIq0QxjFWSidsmZjJbibLdf78Tz/FqoFufv+Tv8U1WzeQ7UgRm4Jkb+qifQdwcewM/E91eBAEWJaF77clE1DaJUko2sB+pDbmxnYdjIRFa7mJ7bQQwIc/vIdV6zsY2ZYlT5Wr143Qm+rkxqu3MV+zOH5oipSlU15aptA5AH4ZobX4yEfexT/8w7cIKwAynucDCoj2Q8S0bWNiBSEFKwYuCm1ZVC6SfDVTJ6z6CGRCEdLb18nadUOcPDsPkomMjoSCIscYmko6aRERIkmCVCqJJC+RsZJ0rjY5fu4QmpWm5cYoqgWxhJAEkpBRpJhIDhFx3JaPiFkZkCkvYfe/vPiFEnzFkLUBREAohLh0xVr7e8BqYBx4uxCi8n9aR9EgkYU7vvojZicgbaxCIUkcQKzFyIR4xOiSRijJVBQPXQnJmYKlVoXKqEe1dBhLU/nlW29gZGgtnekuqnaNW171GvKahJ+J2f/IcZ48fIx6LcMTo89SpUQ18iCdpHvVOkbPznLg8afZe8sm+nImXQOrqUUaZyWd5XKJO394N+eeeJZzokXKtXnVHV9DSvvYZhNrdRrLsi7u0olE4iKI6EU5BNtuC/oUCgUWFhYw4gCk/4GMa3vqyNiNFmbaouE06e3t5eor9yJ5HoX+77B512V84zv3s7F7K1ds3Etc0VGi07zhDXvYs/F6vvsv9/Kh99zJW9+4n+uvupVoXYG/+fsv8pnPfJYb33wrc3NzNJstzDiBiBXiSAWpjf6IQpVQBiFkQqGA0Ilo+xQhyZQbDqGsoFgmJ0+fYWJqki2bRkhmK5RqLsSQNtOEbhPX9VheLNG1tgM/dNEMgwiP4U197HvtEDHg+0m8Vosw0jAVFRGCosvISkgUhcRyiEDFtm0SiUSbPRRFeJ73snP0/4sd/DohxEstp38XeEgI8bkV+8DfBT79f14ixqCX8YM9qFjk1/QTWoJAj8AMkbUAWbhIkYDYpctr98qTcpJypUIuV6QRyrQile/e/yiXXzbJppF+VhX7mKuEbN9+LfXcg9w50ODQ7Emmx2r0JZewl8/Rn00xa8eUvAiRNhlfnmS5toQvZHwjSyLVS6ZiMaz1srVvLU+SAEKakkrJaVFMWhx76lH+7nNfYnNHDy4yXqyhxj3EcQ1Vr+AE40gigYhzyFIny/UqodEgFySJMCECQ3JAknDkLFgy9foSt65azRsu383Tj32VoU0ht9w8SHHkSg7M9fC5rz+BpiwQa0U8XfCp1Ayb1oXkRjbx7N++QN8PYtaPP8z2S7+G/Ut/QXbw1Tzy6EPsGbqJTLwaJ4owcyZheA49a6LJWfTlbib7Y1It6KvERKbKstOgkM2wXF1A5HSktEaiGpBT09TdkCMvnGHb+l3YzijlWoOCnsMNY0TSpGQorF67Bnd8noXzsxCnePbQBOfvX8/uKzeQKV6gVj6PYXioap4YgRs4+GEFSZHbigiSRqgJPAGRHxAhEasvHy77/0eb8BbgGyvPvwHc+u+9IY4jothDSC0yOQ1V9TFMeQVYryDLartmREeWdMKgies1cP0mqhlRa8whyU1yBRVVDTn1wknuu+c+vEBB1lIIJcXm1UUuvaQLxZxntnKSqu3S1b2GMJDIJhOIsEHCEkQ4LDtVwmWJ5qyDs9ggZ21eYTgAACAASURBVKikNJl1vb1omQ52XXUjb3rDL5FJZvDjiOefP4RuwlLTA91E0xSE1CKUAnwsCj07aYRJEsUciayCCCNMKU0kQyS3+9+xBLEkEAS4rk3gu2zespGTp55D0UI6u2H1yGo0SjxzYD9nj5U5e2iGqZM+tQtFfv8Td/OZT3yVU0fHsUyfUKnRjKdoOODNzZCgSVZpkSommK/OEhkeC+Upkpk0thNQdx2qoo5VB63mY8sBY41FmlbMUtCgK9+F3pRRSzESJraiUjcVKpZCHLbYMDxET1cHdqOKriookkzKtGhVahgyxL5LVz6FKkf86R98n//25R8y0LGF/q71+C1BGLkXGT2QQMZCSBoyba7Ai2XeRULyy4xfdAcXwP2SJAngn4QQXwG6hRBzK6/PA93/uze+1GUt3anRbLYwLJ903sUXUySMLhASqiyjSiZybCBCCUVXKAzGdHTmaDkOti1wHZdMIkmzMsOunVuw62XGLpzlP//RX7JqzQjrN23l1VvSvO5NvazZmuLh+89QP6dhNwRqrJCSBFLLoa9jLbKq8dzpSZSWSdA3S7KrSnKoQG8qQ+f6TdzwvXtIdSVZtUFjvrTAsaOHOPjcc6BpUBik4TSRoxquWybQOyl07WXDvlsJX/gZ42fupTPrkmpJRLUsdrbcPmFSG04rxz6xqKAognXre3nowI8xXJtbbra4/ZOXwlIvP7rnGaoXBPfd8Unu+/ED2F4OM9PHut5ruflNV3F+IeCBf3uUke15Ej019F5IBwdhcgFl1c189e5/5KZb3sXCzDSSb1NtDlEPNax0jqo8iTdfw8zlse1l8lJMUAY5hkauh1AxcGSDGVUiYanEdpV8qPDC+RN0dvSwpquD0VaTaqtOOpWlJ9/JhedPsrZ/ANX3WDvQzbwWMFXr54f/PMFd+/8Tb3nXNt75/jdy7MKBNn5F6MRBFxJx+0ZZdjAMa4XWGP5cfEz4xRP8KiHEjCRJXcADkiSdfumLQgixkvz/S6z8GL4C0DWcFLVyhK6YeI6LlhRIcoQIZaJIEK8A5NtadS5uXCGWEpiWTuSlMA2dwZ61aP0Kl46MkMsa1BtL3Hvgp7RimyNHHkEvXYLSZbFtTzdVL+SxqWmcZkB3KoccRXSnhkhH3STNNCklR6PkYJgOS/U6o08/yaYt21i3fhivPk+j6tBoaAxu7UUSAelUDrvmIcsQRB5GQqfW8ugfWk/F0zkzOs/w+i1cOH0fjVqFZGShagkEMrHUntJJYqVVF8ckLJNiR4bS7Dl2DUNxOIUdzeGUL+OxJ35GvQE7dw+wfnAfZy+MIhkNtg6lSaUmmHzyNH3dEt0DCboGJazOMqhjkNGJOc3a4Tdyydbt3P3COQrpFEJO0tvZxdLcLEU1pJqLqTQW+eB7buX1+67hhUOH+dKXv0mtMo+STKOYJk4coUcaUb1BQjOpqoJ61UYXJrpl4js1UrksUSzTrHnYmRBZT9LyAzQjgbfo0dmzlqXZk+y/4zi//I63kEsmsUMPIUMs0khCQYpDJNE2JbgoAiXEz9Um/IVKFCHEzMpxEfgRbQPYBUmSegFWjov/3jqSUHGbGjJJfE+CSMJ1fGQgjkPiOEJRBbISgewhmzHVZgNig77MVjRvkMqURWU6xbOPzHPkwDySXeQTH/h1brv5JgY7LU5PzHPi7DmaXoPLrtpB10AGK6vQ8hs0Wy5Zq4uUlGGwMMCONavI9XegpCyWG01+cOc9PHzfY4wdP0VfUrC6oCC7cyS0iFTCQgQKupLBrSyiKhGaZZLpGmZoeAelUokXTh6kr2DSky3g1kNsrwmG3dZhFCuGLAIkISPiEBEFbNiwlmQ3uBasvXQDcc7iS1/9HmfnamjZIn/5pc/RaE2Ryzfo7qyTStaQrBaBO8fgGpXCoE/nSIySL0JahYzEgfNPMB8s8+H3fQATUIOQRr3M7OhZ7OVx3vqaS/nNd76Rz//Fx6jmQw41x9n4+iux+nU29Gd53w3X8Olb30BUKeNEDaxihshUUdUkvu2xODVPT18X6WIWXwTYrkMYSDh+TCibVOwI5AQD/UWW5+dIJvtwS7Aw7pC0LBQ5QlYihBKAvCI8JCkXoQ0vlY97ufF/vYNLkpQEZCFEY+X5a4E/Bn4CvAf43Mrxzn9vrTgWNBsBYaBgGSamLiOrFsjKRVdiQ9cI45hIlhCqgSRb5LOrqZ42OHNonsnxUVw74vp9l9PZIaguLWAmAjZtHmHr+9Zz5yOP80/fe5TFapVtm1/Fxo0bKWklxk9P4PkRdqtFOpEnl9ZJGB5Lus6is8icU8ElIox8olaD5XNnyA7qGFkIaj7D/cPosoVju2hxHdVKs9xw2HnNm5HULGFjAZyzNGY7McMYLUohmU0Co4HspdvCo3KMLCBqF+KUSw1c3yPZnSRM2jiGipLvY9Yex9VCKk6Nk2dC7rr7QVb19XDF3j1I6Qz4bvumu0dB7ZLwsoI4WoPWKHN2bpLnJjQG3BO88cabee3113D/z+4nl4TAc3j3W27i8msHufHqa7nrhcNU5DT65ZtJDG/jdR97H6nTs6xVU4ysHkQV4DRbOJIEvkTBypHUDNygRjKpUiim8Alxmw00SQWh4oeCKAZFVojEIrmcSqMWEAl4+O6D3PCBLIoKoRyiiAAJBZk2Af3F0uRFd+ufJ36REqUb+NHKB6rAd4UQ90qS9Czwb5IkvR+YAN7+7y0kCOgfsNBUgSJJiEgm8GMSKQtUgaHFSCImny1Qt0MaToKBgR2ceb7CY996lGZDIdcxSKSZ3HuoTiGZxK9Ncu50P6v6K+zYsY7bb7uabLSaB392lof+eYqTR8dIWiaFXIGaO8fB8ftZVVyLpzc4P9XLc63nsFstPNflkp3r6etLETUrqPODVOZByaZYFgpaUadDT1OPFzD0NFN1QX7jLpKD23j6/rsw4mku257h2P1fp1KWsJQcUlKl5i6hR0UUJSTyWsiqiqVlCcMALRHxwL2PcvuvXcnM3CG++dNDfP0um9C9jlU9IRl/gg98qI/XXL4LyOBXQ3BKCMXh2pv28NnPP8bcPHQVcnQmR3HmK6y+ZB1SpofD5x9haFU/7/vSxxl5bDuzTzzK7jXrueq1N/Dh/V/l2zmX9OAAr77ug2QXBd/4wh2sGlzNa/7rh3jm2cfZXyvxrfoh5FJE5ckxyk+f56nJx3nDFftYGJvkjvt+QmdnkWq1TqtcpctIoYcRchjjNGpYGchkXaRQIpAT2KHEj7//OO/+7AeJai00EWGrDnKkQQCxrxFG4cXS5Ofpgb+YmP9XseJDv+N/8/8S8OqfZy1ZgXpzDtOSyaQtrLTGslfHN2TCsI6RMQhCQRjIaLpEqA7SqluMnTtH6LZtTiI5RpgKUjJHI9KI9SIHnp5l8/peoqhOdfoUh89I3L3/OAuVGmYmgSKb+J5Eb3cPfn4RIdd5+uxB1uRuoqU5uMLFjzwCNyBwI0Sg0liOiWOVoa61RC2NBWeBhcUZYslhIUyjdQ2ybvteDh05yOLsGXau78drzOI4XlueWGuvY5EjlGUiCRRNIopibC9ExAqGalBammV8Yp6Onj4UqUWzVqVe8YnNAC0h8+yzT1HUFtm1dTd6rgeiGWIcsumYznSO+bkWF84t01eMefubR0j0D3L+/Axbd/aRyZhEa1djP5vk7R/7DRbPjjInm3TtvplJeYx8pLC0WKFL7eTTn/0M3/reHRyrlyhccyVLF85xz+kjXNo3ws5rLmXLDa9n58ylHHv4KURninMTS1w7vInasg2hRMu2SWTyiChElQWB7xA0JSSRIIgDzKRMEEfMz88SG4JYCIhj4jhEEgoIFfj5S5MX4xUxyZQlienpaeJA4Ps+WiQQhCA8JDnAMA3sWokgapDOGSTUXipLIRNnl1CkBMXODkpBSCDFhEpbBL63p5fy+SVOjs5i+yGOKmN0ruZdt+3m7MwoP7n3B5iajvAEGTPF7b96BcdfOMrjj57g4PiPsAohmmSSMrPIwqTRkKgags5cTKGYYHL6FMlika/e9TUiBYSk4uvdXHvjW1i1eTPHnn+YNWsz1JfnUFs+dVcl0gSy6qIEJqacoWHEICIIJSJZRiCTyWSoVqukrSKSSKDpOuNnp2mVXIzkJI7jYapQWYaZ2QpDfWUK+YiWN0scuoQ1ib1bMxhXrqajO8+OjTbHZ3zufOwh5FQXI92dVMYnyHTvRE/2Uy50UtzXzcxyndve/nFOnPoxBw4/y5GFw8hrNtLUXdbdtJufPPEzXve617F+YJifnLmf5/yQZmeF5WSTY/PjbLthH1ItIPzc3zKzWCcMdZr1iM5inlq9TqPVoCOXxW3YmFoat9VuPDXdiD/54jvId0rMV5rEkUTotZE5SqwgxP+sCf7zliivCE5mz7qc6NxrUj+XR9MiCl0qqf4MraBFKikhixZZyyIIXZyogirfxhP3P07txCSdiWGGN+3CU0wW3YD5ioMRS+R0jdidRlJavO8D72ZHOMSkO8nh80c4cv4E9YZOqwJKKKFIJb7+w7cRGGeYXD7M2m39fPfLC8xNLDF3roYzkSOX7Gaop4drruxgeDjB3qu2sO36DzLXhEhOkRzcwS9/8lOMnRrl6FOPEywdpLE8T39nP4FjEis6rr+Mrvqk4i7ClsaStkza0pBDBzBQNJXluSn6OgZp1gXd200+8NGbSGo2D9/1U2ZKcxgGaEqGLet6GBoQbBg2Wbc+Tz7vkJB1LL0TAo/J+kmWvEnOHYLePTehal3otsHZu6ZRrE1c9faPMWEkue0rH2P33k1cuXU7z/zLY2zft43XXHUd//Svfw0ZHVI6RjZP6CqcOXaWkXUbGezr4Oi5Y8QZBTVvUvDXsjg+z46hTWjHZ/jDD3yUK3duR448XMVhw+ZNrFs/zOGnjzI6eoHF6Sq1VkQoy7z27Tv5vb94G2cq3ycUAjdQcVpt5VsJBRHLxCsWLBeZ+JLEH7zm4f84JlS+H1FZjtCETtKSME2ZWrVBrEhkkhkUScVuBGi6SVdxAFPpQg59UAR2o8zUhbMYuV6iSGFILzDU0UV3Jontpjg9fpyjzxxix94h7vvRfh479jgd+T4SmQFy3WmWl2bwwjp/9oUv8+k/fieDq7cgmOWX3rcDyZcIGxJPPzDJ/FwLM+kz8GqJTKGMuWGawZ0w/Szkhy9hx+Vv5eEHfkxrZoG0Z1OtNBgoduN6HmY2S+wrhJ6OHKrEuo+rNLE0GQ1B4AmEHGGldDZvXc3MWAUvSFKuRIxPLdLX5ZPOSexKgJnooOXqhO4Sk+M1lhZjzo+n6BlUWNVRoNPyqFQaLMV1KgJyfSNsz2zm8L3P8Oy9T/Dc4Zi3fXINlcYYicw6TClgZn6c8WKSri6Fu08ewCgYDOoZLkxP0zQkNl7Sw4IeEXaYnGvOcUlxI/0zOUZnJ5CjPJddv4dvHP8qR04/zxduvY3rhr7Dv/7T31GtNJh1lhk99zCPPHQ3v/Obn+SDv/oOHnjoPv7xKz8CLMamJliqVElkEtQbjbYYpySDBEJq4xpfrFBeitB8ufGKSHDX8YnrGtkVmeQoCmk6LRLJHKUlB0tT6M730tmdIV2QqS/6RL4DUltL0LXLJJJZetO97BraRk416c2lceU8aU3j0ccOIJ3XePc7PsJAcYSW6zNRnmK+egEt22TDpkHUVEzTG2H9qr2cm7yPwHqOnu4CQzv7yQ0WOfZCi1J9mXqPg5l2ODh1knd97Eae/uR9FIc2YVOksTCKNzcJtkOPWaBSb6HlTVIFhfq8ixbrqLJGQJXQrJFQupBCD1UoOL6P24rZcdUleI0XmJ2WEHKSWNZo+ksUeky2qt0IRceNfRqigecLGg2J06dcDp8LyadqrOq4wNYtWzA6dmLGPsdPznH+jr9FP+5zfX+K3/j6R7mQzXOkfpjeHp3VZppcrofFhRIjQ31UT09x7NRxPnDDzfzNd76GkskxUaqhZtIMDAywPLOA3ooYyPQwX2uiZzo4deRZ1g52I2p1xk8+zviBB5g+8TiFDkhp0N9t8Ru/9l5+7f1fZPeuDj7427czsv1T/D8f/xLnj0zwla9+nff85sa2y50Chqa0sTEiIvwF6m94hZQoWloT63YPYtZURMFEW5OnhURXMED5WIC/lGLUrRAWSmy6LM1r94U88N1DzDwbkBXrkZKgmDI7Nl7OO7a/m9hroiddFqJx6rWAf/rmNyknytyy5rXcvO+trBvawFOLD1JllqXqIkePneGt73oLDz28n45Ejr/8za+zUDjExPLjRJkXSG12cSOFC+enUJtzxGFEoWsb4xcuYf93nufoz84iNWRUpYxitK86tfkaZi5BmPHo2tjF5LklGuMBRpAg0quEeos1QR+NwCQIAlaZZYazTc4ueqjbi+jbt+BoGu7ENKuSGmu6TLLWORTVQJCg2WjT2Vyvhus1eP2t29i0bQNPPn2Ix5+eoat3hGrVZ/Muk3Wny2RO2Wz0u1CXzpBdD4nL++G9H+XmO0apd61Gy2bpVxROPrefpJXi9de9FicIeeTJA2i5FL3DA+iSQuQEeHWfTKHIYrWKE4Qk+3wGJwWb52Oujc4g5yc564wzR5bnHze4YvUQAx0RA7s38tt/9M8cnYRcBtYMjLD/odPkhuBLP3ovQrPx3RrCqSOh4gQG5ZqK/BIzBD9w0TSVz15733+cEkWSFDQjgydqZPQsSZEknnLQnIDLe7aQ2TDEV5/+KZ6iI9sWPh5GLkcrnqGoydjNBgUrhxL5TC6OkjR0DD3GMHUGulPsGhzigpZnfOo839//bXbs3svx6jEOPP8zkskk117zWkaGN6MnIu67dz9/860vIbpt8p0+VlFjY2cPkuLSnxfM12bIZ/tQojR/96XPozhpPvOZD/Gpj/4J3R09WGaKSrlBHEUIJSJfzNKmMqwYKxGtQPkVysos5ZrPh2+8nlu2XsalnRJ/9Dff4ekLJbz0Msq69UhKjuXKEn59hoxWQ1VBltqdJ8tqs8wtExZmbM6fOcALZxbIFYsE5Sr2cpWnDzd5zbW38PUf3cnD8xW29ssEYzHDwzojcyGuLCEbHsm0TVIJ0HWTWrlCpVJCsxIkEgmm5+bpWdWD0CQUGSIRE4n4os1Jp9JLzqjheJNM1ifJmYILEzHkV/Pbv/6faE4dRQ1fwK/X2b6ugxfGlnn9q9/C2pEBnjh+mtvfuxtTFzTdgIyVIogcGrZDFMaYZprAkRBECP6HCOfLjVcGJxOVUDYRaZAMcObqbAs38K7tb+GNm/exfaifVatydGRyzJ0sYdcs9u57NZ2rCugZD1l2cSoVGqVlTk0eQy3q5Pt7ED5YIubSjWtYulDjiqu3YZsLfO2ev+PBw08gJXIkM71s3nAJJ06cwBctrn7DXkaDM8wuhHzp8z/i7BMms090kLE3sniugqJoNMsqkt/D1NkWH3zfXj70oc381idX4Xt1NFmj2fCIZJC0kHS+LVNMLJDaqOKVb63QsAK0TEyPmIfzT6KPHuGNI6vJ1CFcaOC2JCIM7CAiVmPWrJUYXq8zMqKzaQMMr9EZ7NfpLVrMzzgcObTA9Ch0WHmsyKPbirGb0LFjD8blmzjZW+QrCzFH+zKURnYymcrjSz6hX0J4CxCUKOSK1Go1ao0qgojOYgd2rU7k+chxG+8eRBF+EKHqbWnr+ePT2Atltm9dTy1oMbXsYZrbuW7Px3jv2/4z//UL38F3NabPTbM8tkx5HIKayXJlmj/94lvYelk3jr1AQtEQrkTSMOkspCjkdAwjWrE0gReJGD9PL/wVkeBxHFNtNFAKGkKPmZ+e47p1+xhSO8kg0NQqkbbIwuwY5dFpmqNJejPruOLqnYw3jtGS5sCIqDQaxAas37aRbZdcQugqVOcbbFy9kRuveys1scBN772cmz+ylyVnjBo19l13FU2nSk9/gtHZQ5yafQp9TcjJcxOMjts89MMZmNzM/OGIgdwAuVwPIurnyYfm+ZW3bebjt99AzBP84Z/dgOe0qNdqKFICNBk9pYLqEkse7SZgiCKHK14zGkL0Ioki509NcfTwOAefe4GpugdJcETI9MIEpeoC9cYSmuyR6VTJd2h0dKn0dMp05kLymYhUGuyWj0AjlYa0YZDWIzKqg1TV+cI//Ah9eDsf+ee/5rf2/yGv++NfpbU+waLRxDJCEoSk0EnK3XTluyCWCGmbShWKOTpzBQLbQQrbIkKRiPF9F0OX0TVBj6qzb+seJs8tMF8LMZLddBaHGOhYx9mJF3jqqeMceOxxliZqnD0EIlCZPrfI0RPPsnlHL/1rFRTRoL60RGlqGUtNkc9k0VSBrni0OSTxxUdbiPPlxSuiRJEVyHTINMIyiVQCbTDJ90b3s2vDRprNBZakGbZcb7L18hFO3n+SN0vvJ5qbYc1rJTq2N3joJ6cZe3yeslvkPR96FQePHSB8ooXU1GnZEkNrB+jbsZlVlwacW7iHhlHis9+8hTu+9gO+d/CzvPvtb2ZJk7BWnSWd07njh/eSyV3N+l2dnDp8jPFjC+wb6cAnBHmEO39c5e5/m+Gue2/n0dPfZNeIhazC9TdkuWf/DIaxhkx3ho41Jp5SQ0SghDJqHCJJNrKUQI1NpJpGPtXFPZPT3CcMvHGPOFtnzxtfw9qOmObJY+SMNGqYpTFXRTMDNDmEUCZsxchKW69bxAG+FqN1yLQqEiXHpaujD3vGo0NZxYHHniHde4wXyo/xoU9dw9zSeVQzy9SEIC9HKKYMoU8Fk4yuYqoGkRyy3CihyUmu2L2XJw48jLZlHYl8GtOE2vI4qwY7WJ2H7MQcXdHl/OR7z7JvR4aZmSMslJ/gsq0p/tsfvopSaYJYLVMpBfze79xMnL2Mr93xb0xMLtPRNcDS5BGEvUR50qW6KPPC8bMMbxpk9YZVmB0QRu4KG6qtQR5F/8EcHmIREnp1vKoDech0ZZmqzzE7P4FlBES6TaJs0ZHooGeDwqnDR7niLRuYK00yVLyMnRv6YWaOy7ddz1JrjOeP/YzKwhI7R15FkDA58vx9nLMT3LZxkXSfjlv3EfIc7//119Oq1hnsSVCqnyDdGbFYGuOGfas4fqrB1vWruW/+IXq3hdTjCyRTEi07wwP3P8OGjW9ibGGGbKHObDWkM9nJ6964i8cee4RGvUGmsIZQclbaXApKrK6wG1fcxNBIpCp4kU2c1UDtJo4l6l6VqbFRtuWKFIMSpqKi6AZ+ZIDjIOkSpmphWW1GvBsFbetA3UDKpPFch7mlCMPMIifW4DbnGVgLe6/ZTP/aDqrTZyhkcjQaFo2yjGc7WAWHSNhIyTRKK4uMhBe4aKZFEIbIsmBqfJre/i40QyOtC6r2AqIRk02qzJ0fI+ic46PvvZXl+e8zZ9tsGFF54L5vcNna10MUsNwoc/0NO8hnQO9LcGuwjyen1zB9rsWa1Tt55PR38Fs62Wwv1bLLwWfHOHZmho0jq8l0dxDFAVIkXlKqvLx4RZQoiqJg6BZJN0WwFFAtlXELNk6Xh50P8I2YZr2OE1TpXJ/g0bE7KcVVNDHEHX92lNbxFB9960e5+Ya9zDgHqRrHaSZPYucu4OVneeTcD1kIKkQJiYZvYzfqTJw7jt2aJdOlMlE5SwsHL3bYsnEdW9f2slQ6RUs6w6tvG+DhM1/HSS6w0Cxx5NA09YkW9SZUA5ulVpPRmQqx0s1lV65iYBAiaqRzSVq+RxgCQkeJXxw7r7gHA62wTqNVwlAlQidAuDGmB9VzF+ghZrg3SVcRUh0CJe+R0mQMWUeOY6LIRpIcLD0im1BJyhaWSJCQ8pTrGqfGapwYbTBVXmbf9TvoHzBYO2ii4xB5LfxA4HhgmQZ5SyWJh+xU0WUJVZKJRIxmashqWxl3eaGC2/CIXZ+UGiA7JVR7kXRYJ2eZLI0/i+qdYdumfnZu20MuM8zwhsvw/RqrhrK4jkc2bZPL1vClcQaGUtz13x/li3/8TZxFk90jV7Jj8y5UXcMXGkGcZmra5fSJpba0hSTaEm4v36YeeKXs4DG0GioFpYNUYKHJIbXAB1kghIoissixQ7ViE+V8krcHvO/P3wbuVv7x3V9n0/oUWtckT8z9K/qOg1xypUNfoQ+jZlOtqPDgNKmMy4XxJTTNZd3gJij4CBExPT3DXNnHVNJ05mRkN2Lrhk4+8au38+BD3+b2T/wS9zz4BE/NV+mT8jz10wvQhOX5CdI9WTKFIVQJlm2T7g1NvvDl9/PB9/4LdqsMCRNZsgibgqAVoMgmiLDt8xhHGPQQhCFBQ+B4LbK5Xmw5wUQ15C//7Xne89G3ITshSquO7Jg0PAdNjdFUn3SugaSHhH5Iy4aOTBetOQ8Rw/m5eSqOj5GUuXZ7hqgxjWtqnHj2FLmBHkqlJg3PYGqqxtp0nnS5QiadwJJMTnk2BC5hyyFwa8hCwzRTpIwkZ4+epSe7k97eEKUoEOUL9BWG6dmZY7XSovTcYSaP5Un07ObCwjKnRg9y5eUVLr90I2+97TX84L+fIZ/Po2wa5/P/ZT+S289zD07w62/7In/9tx9h19aN1OuPMutM48cmIuhEBDkURcGyLDRNo9Vyf67cemUkeCRwWx6BoSAsQIlRPFA0DV01UBWNyA+I/ZDIhUJXEnPQIlGJULvHGLWnmD//PPP6adSUIIibqKpFb67Iz35wmH59I69+1V5a/JRWK6RWdxgeTBJKMW4cIgURvpskTho4rs1spYUVQez6VEoLrN7QRxCCEAqL48tAmqTq47VsyOvExCwsluhcZ3DFVZvYvrvAdNUn8FQINbyG21aYlVSQX7QkDxHeMtl8JxNLDbRcCq+QoGdwK6s3vZNSa5oLCwlEM6IvPUJPZgfL3nOkdAvTjFhYPkMYVIkCmyiIuTB2gXoTfBlcRaY42MHwyCZ+7+NbSWSa1OpVnnnqOPMzFpmetZwfWyD2FDo6Q7KmTy4tE1EhM8P9TAAAIABJREFUqCmosgS+jxw5aIqLJAKK2QyNao3y3ByZLUW0zjQXFmfQhcLJ8iT9mQ4GBtbxuc/cz56rqlzzhpt45zt+l6On/5ZSXWZuSeWH99U5NnaAptze1K69bj29qzZgGCX+5e/u5G23v5lsOoMRt1C8mEyih/JSHSGSF3PlpQKmLydeEQku0ZZv86wQ1/TwpZAoAiSFQImRpZhAhEhhSOAIwlLIqy7dydzoMrPp/QT6PAdfeBiR1ema7aC3o4u4obM06/H0/mluf+sfs/vSTXznkW+jZ1Vsz6fuNOjqKdKrpJiZ8lmcb5JYkQlpRippBK0GnD0xRvemNSTSGUwpSWXpMAmzi+6cQaO6RCJtI8kKleoi61b30aVIXHP9Jv71h4tEkYXnCJym22amKDKxpIIIkIkwzIC50ixhupf04ADrN2/DdjM8+cSzJNIqpxcbJOMso6qJKrXI9cX09Fr09eRR5DS12gLV0jT1+iI9/VkyBRVJT7A42SBSMjhhnnse+xnv+OVXsSG9jc5bNvOlv7+X5VaZ5WqdQqGAmXbI92joCZk52yYKTSLfwRIxslNFTYIuJ8kndJYu1LEXy+TMbhLZNMcbLn6gsmSHnHJs1qzezJvemiWf18llKtx/3x2QSjE5ZfPQowc4MBYQkUbEDXo6BtD0mEsu2YphOPzg2z/lZz8+yK3vvIINxTSthTKBFLPoNpCkgRUBJXFRQOnlxisiwWVJwjBlAtXHkUPCOCSWIYpjRLyCuKPtzBsHEoavYWV1evaYVPInIOORkrKUShKLoxZdooc41Ln3+8fIKxu5bvvbIfEM8/Oz9KdToGjUG3NkcgpWootESqHZKDG/UMGNJbqHNxGIECQoL7rk+ptks1ksM0ml6hOHPsUOhc68jus0EBiYapGGG1NKzHL99dv56te/h2ykcOohgROh4IFitnVIhIckApYroHf08PoPfJaf3nsXx4+eQ6uHpKSIoNREtgOa3iKebrFj706eOTnHiXPTSEywbrCHoVWb6ezbw8BaaEYXCGnScJpAGoUiYbOHsbLHfU/PsnuLxZbUVtJJi+fPP0eiM4mZk8n0FMj2Zzk/uUBFGwApIPRamHGM7DTIFwzSKYt8Widq2njVBmnLoO4q1JsBpVqMaXRzYnQR6qfYd/MGkrLG5OTz6MlOPv/lp5iZh7KnISf6cGKbjMgyv+yzUJljcjbBm2+9kWAhy3333MGJR55hz02rOOdMM+fM0tOVbuuyCJAlFVURxNJ/MAsTpDYlSW3m0OQkiuygpat4QQMRKUCChJ5EMwVSQlBKTqCEKWI7AdX1dCRybO61mG/VePDHZxk3dLKdScaebvJfPvZpevMVHl36CXJSZnTSptZIs3t9N/PTEb4okSt08bo3DSPCRRxvmZnxs0xHXVR9jYS5lrhZp1Gew03ouK4JcsDI7iy7Lm9x4nyT6fEldFSUMxKlxCJ7Nu1Bjh3mJxaJAh1L9ZAUB4FCEOrEQYAqmoRiDVu2vZkLSyk+/JHf58Fv/iXNqYNUm1VkI0YEISnLZM9VV5NdXaPaWOL/pe7NgyS7rvvM795335Z7ZmXt1V3VC3oB0NhBgIBIgiDEVRQ1lKgRRVLWZllhKayxYiY8nrE99nhsjcfhGGlkS/ZIlmRqo0SRojZS3ElwAUBh62703tXdVV1bVmZW7vn2e+eP7G6CsiiBCscEeCMqMvNFZlZVvN+779xzzv19x48sc+jQItfOX+Hc+Ys884WY/tCB6hy5kk2pWGYhX6HfHHDxuau8ePZ++ru7fOVDz3Hlmf9AZzNDzcLf+yePENkdTixNU6kW2NtsYOUMz7XXcZSgEIccmnGZn9f0B1d54OhBnv/k03Sub1KvlFnf3GJ35PLFF5u85Z4av7+xS9dIFu+eZffcLr/2m2fZ2lC04hrSASVTSnZAXiqMcRhHAeevXCIU63z6c59FrBap6B5v+DtP4F/d5gMPPs4ffO1pssUxUZR+A6TqW8mivCoEPjFgT3AzB+X5SEeSiR6aDKEFVqbxXQ/pCDI3ZHV4mfn8MUqFZT74c59g7ugyt63M86U//gxSH0U7CZzb4fhtK2w1L8Px/WzsnqU2OwVdzXiQ0d7NAMlGaweVMxxecahPecy5s+zsjrjeEcSZhRTuhFCcpozGIUiHwnSd+aUqnrXGodsWkCJid0Oy2+xSrGl6oybT03U2ryckaYqvAJFyE8M3OVkpjz7yerYGAf3GNucuDLly9QyFpIdbyTNOAjw/zxOPv5mVwyt85unPEA2u0N69xlRhlrtuX+bg/hUazQJbe3m+crLHeHOXcbRDUMqhBxFZlDEe7ec5dZ504znkdsZ9h47w+LseY1YUGLGFMzZUy4bX3bHMU9e3aDYbKAG2FMxUijiixc7WVerVe3CkJByNJ8jHNCMTDrudgP72Ba5c3mDq4GGePLXNkx99nnNXwCRTUPcxdgsrC5EDiY4dstwIL2/R6UJtFPHWx99E5cAMpz//MaZzJV4682Uqh0q8/uGHKT1Y4slr67cE/q0UeeBVInDL2ORNiZHeQ2iDjgUMXOxchSQNkEqghMCKQopOxlH/AdYutEhUC2HN0l/z+dILl4F5qsUN8l5ELpdy5N79DA5LPm5dYqi6lHWf6akcGYKhVWZtNSaJ91Mr5clmAjZ6DZb2zWBwmHfLvGSFZPk+u32omAolfwVGz1I/GuBNn2O4N008muHgVMT++nVe+NoWu6bMV7ev8I/++T28961/ghoXGYf7Kc6AiVvkCRkID1NaZFA6zNq55zlU7NE8aUj3DGk6g9KGIO7w+E+9liw35HOXP0mHHlIssbkWkEsd7p7SFLlGuTJmuWKxb6HCla0Ra+tDti5cmxhp2hJGf8j8xgqFyxFLwFt+1PDi8pc4N1unJlwe3OqTr83juzF2eUQvncOoFiuHLqOnpzgZLPJs8EbeXnCpehHNgUfSfYnXHb7O89N9Xrh2O2dORfhtj/2dRV76imb1VBWTprhuip80UeSRZo5IjcnEgMLYppLt8f++borpI4rpB4qc+MAHuPBbMef/4IMcspbYHF/i0KNP8MdnLpP4N/pPTDbxSPkWtPWqEDhMZnHXkyASMg2eUpOCtu8ijUUcJzhCEgYp+ZkRJ+5ZZvO5iAfqd7O0tJ97XnuY0r6ULfNZpDvA8QyWgF6vQ7ffR+uMQ8cWcZSk3W3QDiNyiUWAIhiNWb82Zm7eYafZolAr0euF5PMutVqNjY1LhEFG4PVAwNHjh1lanuf5F75AGLjkCoLFZYf5uRV2Wm3CsM9b7z7CH3/qp3n3W/89cdBk1BGUS2VajTbDVPH6R97Jue1VwrjFvulFPvUnH6bk5kl0Dq0dHjzxOkrNPHu9DYpphOVlDNVtFKqGy7vneb67xpGDPiLZo5iF3K073L1QIbxviu3xbfQTSZQJpJey/ZtfZdGHH7grzwNLh9jsXWQ9XCeZneZ5ldBba+G5Jb7wO8+xvTHPW173CEv5KzxQL3Oo12dxsUM58tnaifHmS5zbGHDiwAFyuZSjB49w7vdXGTUVv/mrv4NSUPHqtAeGnFvAUik6GpCGI+qeIl+UHKn3Oeov0Tm/QX8dLn35Yxy+mHF0X40zmyMuzXh8/jMn+cCbb8ed0gTCurEn8wbA61tIhr8qCj3csBe2HInWMXE8JokzMBIlbAQ2UZyiNWRasdfbQUpN3i3wmqMP8Jpj93Df7ceI4xaN9BIb6SX25DbkUhICkjQgn8+z120SZX3qc0VcP6PZXicIexNUh+Vzba3BeJzSaDRwnAmlASZs9jQx9Loh7vQMhw6vUK7kGIcjtJ6YwWeJg8AmiSUYn1HS4+CxKm940xzjcBdSG53aCAVTc8sYauz1N3HdjEFjG8YZ6IRMadycy1y1yuUnnyFZbzDveNQ9n3LNwnISYhPQHYbEmY1jV7GtMo7xkKnGRCHjsM0gaNAJdthsbOAulhhWYTVx2ejYjMcVwrBEY2jRLNY5H9i8sBXSH1eZLVsszJfxhEs90dxdSXn7iSJ7jeukKTh5j8Dk2ekIbKeEMENOnVzHUOCee++jVPbJexZ514U0IwkHWESUchm1vCCnUqwoRQYtRDZh/MgGrH3088RPn0ZU6vzGyVXOjWBkcsTacDPPoDMwZmLn/ErHq2QGFyRpiidBk4FJMcaZkLYySZbpG/QAhTEWWWZIEkPeLXJ4+ggrBxYpVwTnnzlNa3GXNBkyTMeMhSAZpNQrZbRO6A+6KCfDLZSYmakz14zo7Rna7V0euve1jMYOg/4uhaqPZQm0Sen3++QKPiYtEHQk0rKo1ksIK0bZgiQ1xFFGc3dIOZ/Hki6DwYhmb4fKTJH3/+gb+dSf/S7SOIRBjOs7LB+6nWYzJYubzNYrXD9/lbKbJ0sk2jakZsTZU19llj2uX9GIcEj94EHCYhffU9Tqy6S9da5fGDBXyZOzc+x0RyRaMEoTru716QYxQZKSuXXKpQP0Snu0tjs8+eG/YLVm8B8+Ao7HnqrTTwOMgS1R48iih59LJxZ5/RG5umFWCS6dWb3hU6PpBoa97Q2kssmSNXB85g8uM39wkb3eFVrXJ3tKh/0x+ZzG8yCvJvYYkJJIaPZDKtomCBJyGfTXh7yUv8xFJfnKzpgTrzmEKC6ixR4muyFyY0gTjfh2A8FqrWl39lgoVZAWOK7CVS6kEKUTAxjbkYRxQGYsqrkpmoMRtvboVLfIlTIub2yR5A12OEVFLSADm6trfYqlKQrlZaqlHfbaZTpdGAcJc/vqTE9lzNQ8/DuK/PGffpylpQUeevhBWnstyMdMVSvs7u7gFQ2ztUMMW2WWDx9kdrHC5WtfuGFKpJmZ2s/m1jr5AzHVapkr633Wtnrk1TWeeNuD/N6H/x4/8M6PEqWgymVCCqyu95lfsjgwXeDUyQ614hwjnZE4I8K0hZ3ELM7YHKhV2GykfPX8BW5/613sXN9iZ32d+44v4Rdm6bYirgZtdEWSCQHKoVIoUHYUJhEEQnAqMlhHllmP5jgdtClEReyTKaVZuBSMUQWJ8Ipc9Wf5wEFDpjbZ81yeW2uRb+6xK3f5yrMZS7WjLOyr08Hj4mqTJx66k7sfiNj63DRLB6dodbaIel2ilqFg77CQL1Oa8jEmJYhSepHGKOho2MXF9+pY6R41K2Mtixm0+rwwBihw+twan/3qsxx/rIqtklveKHGckn27pQmFAITGGIFAQJaQxskEFaJB2AJlS8IwIopj8nYVhI0lNC11kb3mZa5cP0emhtTzNfJaoaSNI2LCCBqtAcGwgeNUSFMIxgnBCIS2KBRc4njM0ePHOH3qDP1ByPvf/z66nZPUajWMjOj1mlSLhjAEL+9Tmy4xlg7XLuwQDgccWjnB/qXbSJItlF9kemaKwbBJb5iw1Vrjbe94C4n5dRBV4kSw29wDWaKey+MKg+/bjOMeKu8BGpNBGEG1fhtnz1xmlHlIq8jn/+wkhaJHvw/XpntYNYdCxVBaKJDIPbLUoJMIYxdBSIRtQXeDKdunPdhFZzCd8yHok/MlupESlIAejPSQhfoMttdFO4Y+AlIfPcyzFhnWtzUqkJQLDrFQhNpB2obFecHFZ6+QQ1CszNK7YtjvwWyhguN4ROEIg8A2DkpYRFlE7EpGosDOuMu0FaGlQ6Zy5KyUu/KGTzeGpDYUywJpZVg3YvCb1m18uxV60iyhUikw6I8pFHN0OwNqyiUM+wgLlCdxcx5+0SVNU7Y2mqysrNAeNLjcGaFsh8iNULbEEw4+ElcJLJkwToaEiYdlEmxLk6UWtl2g0+qQZmOGgzbDQUCa5lk+eJBBf8Sv/Zdf4wfe8yBHjhyh1dmit7nD5s4O/f4Uft5jFPVRZQs3l6foT3P61Bkee8N3cm1jjTTukqQGmZVotkNUtM5c6RoZMXESUa6v0OsNmJlZYLFS5+Rzz2JkgLYhJQJj49hlZBLy/IUWKUVSx8UyEgeXzFi4xRyh57OXgW377DR3qecTvAmmgZiYFE0mLDwVMictKtImyQxWGqKlwoxGDMcQDosMdntstBrc9mCVnb0QWVA4tkWa5Qkylz3hEcsG5RL4RcneOCYTJZTIEXTXOVKBS0+tIljlp9/9BI2r6/Q7EaGWXN6MUK6g6BWRMsOWMIwliRL09YiaDXESE7kVcqMhC3HCa3zIf8ccx+6ZxZ+GncYAKcBWijAMbwG9Xsl4VQhcSE1vsMNUdQkpHObmlmh3m7juBLMntLlRppWAIhxBt9vFdlOwe2jHwTDxwAvjlIJn4foOU1MWVmTIGGKrAkmiieOUOE2wxACdjXE9xdz8NELOgLFwXIs42eULX/ws1coM84uz1KdrnDu1hQgOUqrUyEyMa1kUCxXGXUMUxfT7Q5TUpNYkldXuRlQ8D+U4bO9ewfLBkh5TswcZhTbTdYf2RoN4OEaLFOXaeH6OtK9JM4ssVPQcmwRNf9QiEYbIT7jrvqO85pGHuXz9GoW8otPexqdMGgdYwiAdENYN5AegC2WKIxtHQ6o1MYbISKJEkzgeGzsjonBMGlmMOz2uS4NfSLAyQznOE9k+u31BY/clpvcVmTuwSMPYhB3DeFcTRXDbLOxsTTa/L+WnaIerROMR68OIjvKwjUuS2PgqQhHja4FQCVEeYgWRculmORgOmHUkj98/xcEfeYJ+NebclUvUSwdubFObFHkM32YhSrWWY/q4YvtKCNpHxQm+q5BSI6R1AwsiEVKipMUw9Ll8qck9d+7HSrpYwsGz8zQHXbrJCB2FBCpl34EZpiJJr5+SpQVGcR/hCEpFj4XpBTxXMxoN6fZSNrfbaAF+PuP4HQ733fkmOp2UZ772Nd75A29gfnaGP/pQj4PLJcZpn3GnTxzaVKs1GuMeH/nwH3DwsKAft7nznodoKc3VjTbtnR7HD3R55LsW+eznJcJd5M4DJVo7p9m4chmhBcaqEY4hCiSOJ2n3t5EubLkdXvPG49x//5spliqcGvwFa+ev8LWX/pDX7b+fxx96lC9+7ovsNHfY6ESktkE6CuVobCkRAgaepCQERgkyBamSqMwhG2YQSDZX+8gkwSvkWcv2aM9V8NsjsqmMWOYZY3FhdYdaXVPcP0ZUBnDqOoVnt7h8tskzu+vs7sLjb3gzlfwSH/nIB5maLtASmotJSGd6GaKMQppxyJ0Uuw5RoqMUl124MgA5zhiNNjgMHC/Aj/9v38uTtU3Woia3HT6E2Y0QUiCYUI/5dhN4sezzd370bfzc//pplHKI4zHKTbEcG6kUllCkCYBBSInnlxiGI9LEQjDJizqOj2OnpFmfIBZYQjNlMmwBjhUTkyeOY5AW4zBhMEjIYk2hkCeMQuIsncSKqaHV3kUGY2rVAxw5cozV1VWOHLyTStmiVC3QbJ5np32W/YsFpuuzeHaJ1m6Xe0/cy2Z7jZnpaVzfprm+xublVZbmyrz5nd/Jqctn6I4i0CHb188xGI+RCKq1WYQQdIcdBqMm+Sk4dvcC9732KHML8yjLYWvrKq1AUJtZoViBokk5+eSfs7e+ipu3oJgQS4hMhp/4+MbGFjbYe0jjYKScoHYysI2hhCAIQ0zqYac2YqwY9kDbCaM0ojfWCNOjMxjQ2WhhkgHF2hylnEv/4iVWdnocmV0gKeT4zEyBC80W06lHoDJimdHcG+C4OUhGoDOUktiuJEthHESMMkPHscl0SmJ8IlvS0SFP/MgxtqcFolKEYZfmbpdaLMGapAaFNN9+hR5Dwn0PHSHVH2c4HKJ1ylTJRtxoLcVI4tRMeOkKfN8lDlx6wwFlT4NMQMfYtkUWWwg7h3RsdGTQOoAswJAnTjMQijhWjAYxJkmw7RjHcej1O2TGJpcvEI4FqRMRhiH79i3z9JlPcHgFpqbrDMY9FksFjtaPc+bFr3LpzCpHDh/lzjtvJ4kUjizS3Gmycuwo9cpBrHSP3ijk7gfvZ/+hiPWrPp1mg2Fng+rsPlxlEfSajEcdgjTjxKMz/NBPvBesmLXtq5y/dJa9dh9le+jqEkZn9LsdNgYt2uvXCMMAVbFJZ4rEiSBOLWSoJilWo8BWWKmDlBYxYJkIO4twpQMiwPFzKMcmyVKiJMJqGKJhQGNgGCQd+j0YtoeUSw6FcpF4EHOg1eP2ks2di9OI6QM8earJ575wGh1f4I0LNkkacmRfnaw5ojfaw5Uw7Xo4QCQgzoHObIgdjIAIC3e/zTvffTtHv/9ezvavg+tQSiVBu0uaKyLNBFYvJVjilRd6XhUCFzJls3GSIBxi+7WJV7QYE8cx0gJtFJmwkAoUknwuo1xVbO5eQe0vo+MuajjEc6rIwMWxirgyI+q3sXIp5QpstUfEKdiygEmmCKIu2otBj5COYmpqmmZrzMbGCFu6jJwuadSm1wuZnp7mU5/5DGH/IRb2LSGtAb1BwIGVo3i2YHFuluEgprk9xC0WUSJifes5yrkat999OxdePMczLzxPoBNm5xc4/blPUnRithpdbJXx2IM53vXfvYmFA0X+5KlP8dsf/QV8f4rlpbtJRj6e52DnnMmGCTIiVePjz53ENzOozEa3LPytCuYGk3OURQyzFHTK7nqe2+wqXt6HosT1BygzwjgpIpcSmSEisbCSBOhR3cozKrqsbYeUlSRvVylriV2wKBWn0K0R780LVlwLtk5ydhXaVpXUTkCmvPax13PxU19EtVu8ob7I8biNowTGxGz1YrRSNKsRZpgn1/Jw8znMuMeJOwr82D9+O+c7TyF2DbndAYuuZOC4jNGTiU4ayF6OOPybx6tC4EmqUbmYn/zph/iln/si2ruDcFDFmxogrDE61eTEEVxtkKaFTY9+u0e9ME82dDEmw8pcwsGActVhaEaEkcTtFillZSpWBVu8iGfP0h2CsRN64wYLuTrdgQXKpjY/xskP6e4OGW4sseVr7EwzV81T0IepKo8XdzaYPXgXe2GP3qDNtJuisRkHa9SmMz70sTbf+9bvYGPrAtWZBexeip0/Q315wJ/89r1E/Sqvv8vm8ifPE47L5Eu73HEXvP0nHqM1HvDU0xfZ6U5TntuHkJLmMCBLQWYuIi2wYBWJooirV3axhUS6BmlJfNdjOOiAUfheHq0lWWojpWRaCVppiBkEWGOLQqGAbRdvwWo9bhRQsoxCNofnb2PlYw7ZCabTYdyLGbt5VKFMueMwe7bLr35Z0vcka8amfuwQznyG3O3gFSXP+NA+sIB3rcmdSchKX6OLDlsyJKhMFrkmWiY0MaFlkQwt6rkyM0tNgngN2xh8p0je8SYhpR2TiTEGATfSp0n63zAGF0L8GvBdwK4x5s4bx/5KVKCYdKL/AvB2YAz8sDHm+VfwOxgO+ywsV9l/pMD6mVWq/kHSOEHZYERCYjpIR6JkhrQcpGVjhCEjRNkWuaLCslz6gz2M0ViWQAUjoiQkiAfk8zUW5nLIZp9xsEvFryC0Il/IESYBYTTE8zxmZ4uYbg5Pj1Bogu4O1aUilUqeqZpHPAqxYhulC+goJMSitxcjpWBhukq/0yUaG8aBhaUMRmhUucZzZ5+h6t/FnQ8dJvpl8FSPd33vMY4cu41mO+L0hUs09vpUZw7e4lJKLUizmCAKwQUjpmi3OnQ6HfL5ArZyyTJDFEU3nJ8EcRxi2x7KFrc6F2/ugBFisr/y5bRlKeWtNtQ4jpF+ii0chJRox0IJj7wN1e4ay8OU1y/X+GebGeOFMaV7FgjnS8wvKH7wB5dBuiRjiejU2dve4Vqrzd2lCqGAKHPQyqY7GmLZKb5rQU5hJQqhIt73/u9H2SMspREyRZsUQ4wWKY7lojFoPfl//moozt9S4MBvAP8e+ODLjn0zVODbgNtu/DwE/PKNx792GGNQNuxbKXLgmMf6Sy0ivYuvCji2i7AEiBGW7WCEZhRAkhkcDMaKMEqA8rAci4Ko3SABGCw7wnIEqIxhxyI3NWS6EtNOR9RLR/E9hXJijB0TxhrbyuEWiwjbYmWujjCSVnOb4biLkVCbXmGmVqHgjOk0DKnt4roFgmCA7KfUK/HEJ9Ep0tgaoad8LL/KIPBRBZuFxTGZ/wzvei8cP/iDFCoW/fGYF166SGblmdu3gDaSOIwmSJMbJxSRkcmITqdHo9FkOBxTLtVuZJcykiTGsV20hiAOsCz7FlPSwC04rTGGMAxvmcnfFPhN6nKSJIxNTCnnMO2UMNKgsxhGTe5KGyxdaLB81zJv+4kS16b20y7NsdlJqOghaZiR6RH50jTWoTqdNY/eeEzbZAxCzfY4ZCtRdCJFtTAkl/NwXZc0i2j2rzO7UGZk7WHJmEw6ZJkhJcIIjeMUSdOMKIuBb8188xV5EwohVoA/fdkMfgF4zBizfYPD8wVjzFEhxH+68fx3//L7/rrv338sb/7lR1+HbSk8L8dgL+XCC4pf/r8/ShzkqNXnKUxZCAuGo4AssVGOoVrz8Aoj0iycwFaNolpeJEkmMFbXT8jlFZ5vs1gu0+1fZdAfgSkTpUWEE022bNUVrqnTagwZDgdUpxPmvB6lYh0sh1Pr16nOPIDjPEDQs7n9aIxOXqS9voXj1slsQXUmRy6/ztbVHe468TqeP71NbEIi45LaD3Dp3Am+87Uhh6b/lJos86/+92dYMwmel2Pf/oPEacZoNKJSyhOM+7iOjYlTXJXDsfOM+jFnP3sJy7LI5/PEcYrjOLiuSxiGxFF6S7BhGCGlxHVdLEv+V+g9cSNWvzlr3zxm2zahkyMb9FgxIXkh8GXKckHyY/Mhtx+ZojNY5z8uVNiuH+BKIyPsQRpuM5Mvk8/n2cmGCEcx5RXon7lO5zOr2FaJfuayKnxi5eANm+RcBx35RKMYtxjwicbPcn7vKzSGLRhUUZkijmMSIVBOniRJiKMUrQUIi3/6+J+/Im/Cv2034TdDBS4C11/2vo0bx/6rIYT4CSHEs0KIZ4fdlEFvTLffYRg2yJwGM4sJd9y1SD6XwzFxIvf8AAAgAElEQVQl4qHDsJ8wHPUp1coUShWE5RInDlrn0cZHWB5CWVi2jbAstPFBFIEKQbSFzPI0dzI67ZTKbBm3YhOkIaPhpLChtCENIoZDGDJDO55ioFcIuZdhcpS90SyZyDEKY+IkI4pHOI7GczVxMgBbghJ4nqKUjygVDKXiLFtrguXpGcpqyHxFIHTCkSNLuJVZvEqNIOxhy4TpWpl2u4N0XHAkxs0w0hAHhn4jRWcSKZwbjwpL2mTppAEp0wnapFhKIKQm0zFpNiECv5xQZts2juPcOg83xX9zRreFj4VNFCWk4xAxCDFDTYMKH3nqEr/4pQGbcZHRyKYsikwJH0vkuHppg5N/cZpCoUScaa43GswfPYhVzdGJBvTHPTxbkIQDROohyKFjQawnWxTjJCHLBEJbSOGBsEmxSLU1AcBm2dcv1P8/na3+OlTg3/C5WxjBfUcLRgoXLyeI0z6WHXLb8Qr3PbDM5uoqWSwIQxvhKxzbw8u5AGRZgol9pKVvzEpMUl2WhSYjCCyEkCSxpGANyOeOUchLNptNcnEfrAxpl8hiMFaA0UPGYYwOj3OhVWCqup/ZwmHuuP8wjrdEklYZtM9hnKuYNKDTWcMvgG1nxEEPeorMlEgyC9vpIVUOpabo9QXT+T2ajZMki32ubq+Tn3Ox94r4ORule6TBAJFkVCpVEiLG2RjfgXQUMWrE9LYyPM9HKUWaZjiOg9aTLsuX7zRP0xilJGk6sVdTlnNL3DfDkZf3ddxcbMLkQgiSAXbOYoyDCSLSyBA0+vzjy+vYBajeKVio76fZGuJqyOd9SnYNf14x7HaIx9mkrVUrer2AWFhYno9jW3iOoZwKdDTxiJES8q5Pa9hic2sdVZI4ygXbRgswkSDTTHCCSJSURJn+lmhrf1uBN4QQ8y8LUW6iAjeBfS9739KNY3/jCMIQbVs4OQdHOUR6h3sfLvFbv7FF58oWhdoxluqzVOcXaY4a5HJ5gijBdScFnCiO8XJA0Mf3XfLlHBvrHYII6lMFtncU09MZxbkKZRVwZW0HHSsOLixi5TP68Q57xmGQewBn9t+xmdq8eK3B3jMNPNlBiD0MNiYeY+s+3/fWH6SwcDcvXftzZpZ2sPN75LePcf7UHlN+wNCk9KMiO4MK6yOPuj5NuHkOYaWs3DnLbK3B0pUK416fjBRL2sSZpjpbpNUf40kFw5jtqxs0V4dYYYl8fvrG5ltI05s+fZO02WSOMWQTRWApsBB0Oh2mp6dJkuQbFpNaa5RSuK5LlmUTWwspMckaxq8wml6iO0pgPEKHHR58zzEWT8yiCwkX1q+ibYdG2CeMBEskTC1MUZ0rc2mrheOV8HSJxuaIk1cH/MiPfYA/+/Qnse2Mo0tzeNY02+sbHL7zAN/z/W/nX/zCP2BqUbK+16SY8wl1yjDpk6oQYVm4lMlSgxGThXMYvHKB/21DlJuoQPhGVOAfAz8kJuNhoPc3xd8wyWpqEZOaMWmiSWJFkmTMLxb4tz//Th55h0uxNqTX2+al0+eJoohud+J+mmYB2kRoE5OmCUJMyvpaa2zHgBwxDneJdY7OsEuY9HFcSS1fY6ZUZvX8aZq7WyRintS5E2f2CZ5es7m8HdGNHex8FduDTPSITBO74rFw+H4+/ImzLB1+B/c+8oOstaCXFAiHPeIwIQxDXHce2zvO1U3JwSN3MRxt0+mmbKy72GaKqu9y96E8BFsI7YBdRLpFdhpb+JZNPvVpnOvRXY9whIeX/3q24+XcyK9vxP2rRy6XYzgcYts2uVyOJEm+wXrhVocekzh8yivgJ4KkFaJTQz8bIsqa248sULFi0vYOKhyigyGkKY4lsRQYpYlNhlQ5SG1G/YQLF9bJfMVLG9c58fqHOXDXYQIx4tK1i6A0n/zix/lX//ZfctcDx7i6uTrBuScxUqTYDjiuQdn6RrdpBuZG8kD9NwTBCiF+F3gKOCqE2LiBB/w/ge8UQlwCnrjxGuDjwBXgMvArwN9/JX/EBDkVok1ElqakgSAONEaEHL+3wr/5xR+lOrfH9vZF5qfrOI6PEIJCwafX32UUtMl0SKGQm8SkqSZJEgolCz+foUUXlMtwPECnhoJTpuLYTJcFx49Ng0i4ujPP7vAehtxDHw1WH0OXJN6lt3ORsHWJbLzOaLzB6rULaFz+469/klgc4K3f/T/T7O9nGOwwM5fHczOQUxj2EYY5ahVFNryOimHYFgw32pjGHkv1EZXckFy+wG57yEajQyHnkw0ShlsRnSsQ7+WwTBls65aoM528TOzZDYG/7FSarz+3bfsbENgvN825mT15+QUishxe5OGPRtQLhpkFi7kDijwjkmaLaLtPPsuRi21Kic2MmNDqwsjQ6YekRpFmFmGoabT7LN52mNXWJj1CdCll5e5l9h1Y4eKVVQp+matrDXZ7u3g5F6MFOhVIY2HbNq5r4yiFkBmTu1WKsgRKvfJ5+VVBeFg4mjN//z8fo+gblJFIY+PbDp6bYbsRUdLjjsPv4hMfu8z/8399Eu0vUSgU8HwHQ0yWJezt7VGrVfBzNtKaEHMXlooIKyUIRqSZS97KkXdLeFjstk9RmXVpDiMy5xhn134Ymbsbci5bnT+nEPSYq9U4NL/InfsOIqUmJmSru4kiz+WzLf7iE6dQ8zUe+I7jPPTICfauvIeF6TK95hlmFt/BV07m8Kf2cfi2iMbT/4VeCzJLcnhhh/tvm2foLvDsc1c4eTZHpbaC7+e5+OwzhM0RDFzK1lGEJRnrLrG1h2v738CpEeLrKTNzC/XxjbO5ziS2bRMEAVprarUaAEEQIIS4FYNrPZkUAr+E6I+YqSY4C2MWj3vs35cnbhuaA5dW7CIjRV6n5GwLW0k2w5hee484yQg8F6EcCnaBnHEgCpG+ZHewg+1GXLp4jWi1xMrcPq5fvoy2I/7hv3kvR9+yRa2syAKb0cgmUyFYKcZIiK0bYZVBKo84SvnZRz/77UN4MAayzEVoC0GEJUOUZZC2w8ZWk4XFKbYa57n/gcN8z/c8ygc/fIZSoYJJbXRmo7NJU9Wwm+F7E0KXNoZwnEyKLalNEKQUyxboAMsTaJUSizkyt8r1ziL52UOYzHDtylOQnOaNDzzKkYMHuPf4UQ4vzpMmEKRguRHPPPMc05mgc3WBy8+d5KWc4NCh4xTLT+DlA7bWrrK5ZhH0y9x5/3FE+gxZsp+dPgz8lHjoUB3ch+M75BerdJ56Fqn30HZE1E6JBhO0YRh1SZIM5Wlsab8s1WcQQnLTyPMbx83ZbSL0mzO467okScJoNKJcLt/KjWutbwk8TVOCZBejUoq3rxDKdcK4hwgMvUDSSCU97TGXWfhSkmUhrfGA/kiRBhl530XbgkE6nhTaRErc7PL4449x/qrF6s4lDi7tx6keoLG2QT6XI3Yzthsb3OP7QIalJSbNMCIBK8WSDsKe2OYZI0BK0lfunvzqELg2ECc2Is2DlQBjpMowxmZqapkwSLAJcNwx+UKAEBZ77T4Ym9c9+jZqtRr9focvfulThEGK42ksZRgN44nNgHQxkUWahIS6T6EkwFGMsmmagxV2eovYosPe6U/AYJ1f/Nf/A8f2HaJS8Sj5FuEgQCqXmYJEG81Pfd8jtFvgacUf2T0uXDnLx/6wy6/+0j+j4l6i5iv+7I9itD7AeFjAdUq88S3/modz9zCeE/R7ZygECwyjP6Mix5SKayS9Ib3xkKhjcJ0ywlYEpolJE2zh4RqXcZbeymHD1/PZQoi/Qutfv41n2YTMYNs2URQxHA7xfZ80TYmi6Bs+lVe75GZnMQtFVFilqBT5kUU8CAilRLl55rSkqATjXI4xEL3UxkOTVwKKFsE4IDFjbNvn+pV11EMZb37gTfzS71zD8jwSM0KLgMpUkT5jonSA7eWIgzEi1SAUQsYIOYHHgg2OhcDiW8XVvyoEbowhSQQ6s7EQCGviLBvHPkmcI0oFrq0Zph3uOLFCHFzAFh6eU2LU1dy2sp+3vOm7OHzwIB/6yL/DkgIlIQ1BOhbKcbGET5I0yHQLrSwyyyMOK8T6EMo7wN76GWg+z71vfID7F1eQEux4SJoFiCTBsvKkgcJTCXoomSm4vO89j1GcUfzKh3dZf/rTvPjC/8QTrzvIe97xD/BkzM7gCAN5nVxuyJX1WS6PHS45u4SJwqwn3Hcc7j9xD69/5I18+vf/gCsvXOfw0u0kFoziPlY+xDUGwgCZSTRfL7nffLz5/JstvKIoQqlJ0UQphWVZtNttDhw4cCssAW4ViRbLUD8yx6VoRFHYzJYWWZAZ0UzMIM7oxREXn3mOUT+kW4F2GQ54B7GkwCImnyviakmaaHr9Nr2dAR/+9d/n+77/vyfpGhr9HRI3oe6XWZidIpelCFsjZEIUD7BTgyV9kCnCSiZrBnPzQpZo/a31g786YvDDOfMz/+kOylOSTMdok1JUBRQGo2PQCVqBsWyM9Fh2Z3n+uYjf+1CLjn4v9z/+nSzfMc3dxzx+6R++m4XlE1wJyjzwxCOMX/ooVz7/G5h992EKXdxMs1Aq0vFrnN5ZIUwfZbCd8Mi+Vb77LW/i8ModOKpByZ2n2dhl3+L+ib2BbVOdytEMejg5l263y8H5OYoW9NoJH/qt3+Znf+1zHH/jd/PwA/fxf7zvIF96ccivfOEMn1ttI3oDFpVmynHYDXsM4hGDgaK2sI+CDz/09odIN57l1//J+7EFCMvGtRQkGdLySKWH5uv35r983r6Z46oSRZKojxAJ0rJI1aSvIx6PyPuSkp/QHQ0Ya80b3/39bOozeFZGbtjg6P4DRGPNmXMbrF5PMCi8fI4DR5bIZEqoU7QUiNRGRxZpkFGSKeNul85ul9naEo7M8/zzz6Ncj1JxHxdX13AImKmXkfU1fvxnHuGnfvJdfOriH9EbGLLMIxMgVYJUIKXCdlN0Bq6bo7U7YjTW/NM3PvVtFIMDWSrIMjMhaRmJEAadpUhhQAnSLEJrSA08F55l4a6Hueuc4GO/9xRbCzXGZhmsfbT6da4+uc12r8X3/OjPUFyw2bh+ku3re7hGU66WyVKFY83TbsbUF1zarQu8/n0PcHBlkSwNyGKXftZmfmkaIzJmp2rEQUK31cXybGzLw+DSGaSEUjM/5fDod9wHH/wyjX6Pc9vbnN46yOpOi1PPPY8JJMv1AofKBZanpynPHmEcjeiFGRdWr9AbRnz16Wd4/f130Oh7lJ2YkgoRjk1mOWjLItEJtmXdEvbNgs3N199M4JoYaU1McyYpVA1a4+cUYdjj2LFFDpcX2Rk06ccXENoQhkP2zdQwxtDtDZmaXSA3XWUwHBOnEYNxh0E4RguJ7edwkyIkgiwIiYXFXnPMtcvXuZo1mK4dZTQs4GkXfyHDLXRIk5CNfpcf+7tHeO2bjrMWXcIoAwoyY0h1hiVAWhIjBEmcYVmKLDXEcYqUr1y2rw6Ba0MQJLixdWPHRkYURXi2QNnWpEKZTRZESZrREDGMW1TmbPYufpkvh2Nmeo8RYKhO38+Vi6fwakfYG3gcPPFavKX7KTRfoB8MaQsNniGzpjCJptlsQkWwsFhnHPSIA4siZeK0g8oVKOTzPHf2Ko60mK6WmKrlGfYCHOkQpxk5z6Y9jDl8/CgEMXt7PZppxvNbIec3dmleXSVXn+N9b3qcfZUCrhD4nkZrnxHw7kdv47c++kn+4vQpWp0xb/u7/wtf+p2fx0TboCxSaSGkIs0iLP31MOQvz+Df7E6sxQhLSoSYnGphDAiD40hGwzF+2eLeh46wF9d58tRXKPtHGYwCSvlphuOQYRgh7SLd0RgtMuycBVLiaIU2NgqbQatPOA4gydjZ65EEQwr5Kkmk6XViatX9jKI25Nd5x3v2g9Nnt73D//gvfhhhdzh99au0e22UMzXxwNEZlrQmFS0EaZKhlEuaatIkw3a9V6ytV4fAjSCOLTAullQomQLpZEe9Y5ACHOEgtUc4TIiuHeBrm23OnmrDchnmp9hth5x9ocH2J58EE1M7cSfNwOKFUxEPPfyz/NHqL7NwaIVW6xRbUYvLLxjK+x5kt7POvY8cpjPQ9HUH13aolg7S8ev80n/4IF975lmixg4Me1i+4qc+8G5+8sd/hOV6jb3hkEGSMj2TBwskLro3YiTyPHl1TEHVed/3vZsPvOMRTszCeBwRxZqpvEZmgrGagXGbd/7zD/DzH3maDz19lf0PPsH9ratc+uzvkFqSQWrh2TbKxLfi5Zul+ZeX6L9pqGlGIPKkWpJpSaYyUBm5WoVDx5f56nOfZ2fU4Il3PsLK4TKdc23yRjMYpuw0+xg7T6fXR+SqRFHMcK9FyXWplepEITR3uqyduUSaJLjSoewtoEyRNI1xLQkFh629cxirxVNf+EdstL5EIk5gOTafefH3mZ4rkasVkGEA0sZGIZW4QVab8JuyVKFTmzCMsW0Xz8u9Ym29KgQOAqMtwijFwYADvq3QOpmELVaGlBIlFZAx2taIuIBUKeQkVOfBqpPgQ9QBOyCn9ijYimAUsbc14qUrAW9/7FFy83XWL3yVIM1Ry5Wo5+vkSw7NToJrQ6VsGJmI3/7DF2j3JCaVsHkJTMIjj7yF//zrv8ri/DTve+8PkEUxSSYYDfIoD6qlKt1SBTuziLVHoTzDHctTFFRKt9UgzgQ4ORKjIQlIpcW+mRlcE/H+73qYnVBw7toFDt91ggtPlyZFrzBFOBoHSfzyWs7LmqTgm7eQCi3QRpJpQ2oyMpFiWZrN5jbjbEyQKC5f3WXxzDqV+VmG1haVqSr9UUSYSKI0QStFkoVIS1MuVykIn2SoaW612N7YoezVUD7EYYKJNY7loxwfpRyu7FwEa8SRB22k6hHoPRJRprHWoFyv0RuNSbHwvTJJDEIKlDUJpbROMVojhYMxAq3BdfxbKc5XMl4d3oRGEKeGYBwRhjFJbNACUqPRJrvR3y0mdghGEZuMwbCHp2xwi5RqC0wtH8GbmkXWctDbINq+9P9R9+axlmXXed9vj2e4w7tvrKmrij2wmz1xkEQ2qdGmqNCgJDuSpdhKAGeQLQWwkUCxEEuCITugFSSIHQNG4gQQkjiJwTixJVGiZJEmJUUURVFik+LYzW71UNVd83v13rvjGfaUP/Z9Vd2KhpaiAN0HKOC+Wxd3OGeftdf61re+j9jOue/BMa0ZUk7Oc9RNYPAmer2NKAbMF0eYwqOUo081q1iwFIrn9q9xc1pwdBzpr19jQx+xbQ754if+JcvDY/7Fhz/Ksy/fQmrLfRe26RYLigSz1YpxUTPWFYSS1bKnbVe03YxAT1KSJBVRWdRgSBBw9daK6Y3rnBnA9733raj+mDPn78GVY5IyEAMqeLSQd5COO82ddSfylUy73/9PRZX7DBH65PC6w2vP2594O+fuvcgjb3uCxVzwiX/zWbojSVUldnY3WHUJh+V43pKUJMQGAWhRMr/Vce2FfY6vHiJWnthq+qVAp4IUe9pmQdf0rLqWjT3P+773TfzvP/df8Oz1p1m1goPjKeVwTNcHojcYPURGg0xgFFiZ0ARUisgYcu2QFDGkNez72pfW62KBp3VHbrXqaZqOSK6ei6KgqmsGgwExCWIAaQxp3BNMw7gGpjOqPvDQmx+k3p4QfUc1HnL9C1/goz/3YT79uZuoU6d4y8P3o+2YcnAP2zsPYJTEypbKdMi0pPGJNmmmfeLINYzPPUjTJ9i/zul+zqTpGPVLGGzx1OV9XjpoULrg5Sv7bG8OOb59zMaZ0wwHNdvlEOUkxlhu3LrJ9cNbHDYdLQqhBwg7JKgB0oBXJcvOsTg+5B3nK4yfslwuueeBh2maJRuVQobMvfmjjhAC3vs7acwJ7i1iSUiCqBJ9atk9P+Ft73kUNZJQCwab27zpvrcwO4Sbl2aYKtC6huOlY94KTL1B53p831AqQylqblw64ujKDFaBoSio1ACranzvsKZHmR7Piq6f8453n+bHf+r7EKPnCTKiy1P4qFi1mf5bFDXdKiBjwspEZRNGBKyE2loqY9DKsFwuaZqOrutYLpeveW29PlKUFEFGkhD4CH0HXZdQhaLpIsSOZesRsiRFgxh4kmkoCsmpYs7NT/w0zc1LPPLO91CPe2JUDHcvcGPe8fMf+zjh9g34zH/P9/+jT3Nx+x6+/uy/x2f+2Q+iRmcwraObCW70JcGOKPsB40Jzz+MXWB4/yvFXz3PjyuWsKe5H6K1HmexM2NiY0LqG8Zldnp9H/sE/+Z/hwgXOXriITg4TYx4n0wXPzTt2732M1Tzx7Jcv8+XP/hoPP/IAZ8+d4xufuJ+XL23jVpEqzPjL3/atfPrzT/PA/W/n6v/9sxSyo6g3EFuTO3ySV6Ylf1AOfkLGSilhU0WnGmQdOX9um7MPbdC4W3SNxzlJyYhT92wxGTzGmdE2C3HI1f1b6OoBhIg412G0ZqesOLox4+jqAeFYU6cRhg6rHK0KJCRKWlw6QqgaZWq6NvCB7/sWRmenvLD/K0zbAUZdIMUWKUErgQgOYqLQPYvVbTSS0gwQslhTfS0Hc0nTNEipkQpCfIM5HSNA6QRKIUhEFDFKnMve7pLsxhAj+JgYx01mJtFbwbkHNQfTq8y++q95bvYMVhyxHEnc7hg72aEUmqNwE/pb/MbHf4HFu97Hd3zT/cih4eZLzzOcnKWdRRqOEFIh2oJZM2V4Ht76nnew2v8Az/9v18EOYLjDaOcevu2bHuPMpEYVkiuzwC/85pf5pc9f4sI7H8EOa5ABZMLFRDQlMw/PXl/yGx/5KF/4xMd58fOfRBaKRx6/hx/5z/8u7//At+JmWWD06x5/G5/70gtsTbbQMaBlhOjAKNIrJMte1cX8fc+9kmHYxB45SOxd3GFzr2SxPCIJcq9ERPowBw+FCQxqTS83OW4bFt2KvhMYq6m05ejaLab7De00MSy2Ea4nefAe5n2PlQOKYps+BBbLxPGipTBbPPnbV3j3v/Uuzp55B2F/ye399YQ8CfCkJEgpgvBoFZEquzgIQAiFUnepBMYIUgp437/mpfW6WOBCgFQJtEKZPK0SfKLznhQDSiek1DgPrveUK0MlBhyHFcVewfl7Kw4uHxD2p4z3aqatQm5t0yaNXCzh6JBqY4MbL36NT/kR84MZMXmIghhGuNZz4K/QH06x9WnumWxw9dLnePPFe/nG7/pubh3D/LiDruPxx8/wA3/luxgPFZ3UfPRTX+KffOiXYXIfg/EOSSm8higTIQkwAxZe8q8++mle+NyXafZvMSkE09WUoT7HB3/yx3nfX/hNHJJZ49jdM+zubXNwo0dIjZQeF8NrIvn/gTn5oGTnwjbjvQq0x68ctixpmw5dlJhC0xwfkkJg2U0JYoASBolCEJFRQAO3Xz7GLQMyFugyEUKukySKrhO03jMcWm5PZ0hVMKq3aTr4hQ9/lguPDfj2772XorhNiEfrIjGzA0mRkHLwstaidcR7iC6CSAi1DnlaYovMq3nDWXknIq2fo6XB2AqlDMvVktJmtVkpNdIWuC7RdZ7eX6WsCkaipKNg76FAuWORybOhRrz0qy+Qho53vPsx4uIql5Yv0rx0Dnv2DGbnDC/MA1/3gffz4vM3uLZfMC4SG5Mn6XzL7FZDkMfU82d48hnLeHIPf/69b0WHxMAIvvtbHuXajctceVry0z/3KZ673jHcfZjdjVNMym2QLV4neh2odYEwFbfnMw7FFlcOjuDKM1zQt7Am8YXf/iKmHvOh//Xn+KEf/B4O54ZOwju/+Rv4yId/jqWsEEFSm4q06lDW5PP1imbPSaR+5VjaaDSiqiqstfg3GYZbkVVzhF82TNQ2rAo2dUnnAjdvv4Ci5dTZPfrYMbu1w43b13np6Ck2trYxoeTW7RZxVFIrBdqzcreQxqB0gfcCM3Q0y5tcOz7iL/6Ve7j3wT32D4755Y8+w9EC/uGP/SJPXXoL3/kf3MNgt6U52MElR4weIyQqGZq2QWpNUoIkSmKyuBAJoaNtYWtrgrWW+XyK0PYPXUu//3hdLHBIefRKQUolKQqCi8hSkcSJP0u+mCEJdN3TH/dEV6FEiSgsg9PbjEY1W30J6TLx6UvovxCg0ByvbiN6y87WLp223F4seeKJhzh97hHa2YTDq5f4vWd/MdsBKkkvjnDXV4BlrDWb4222xgMqEXn58lfx0vCFZy7x8u2WrVMXsfUGhTHICFpbWpGIJLQqICUmm1vYgxE4D6ElpQalDdFZjg5uc+XSi1x++Zi9sxNu9zCa1CSgSwIdJCNdorr4Ktng39/JPFnoxhi2t7eZTCYMBgOujg45mr5MVQnquqY5cJhkEGaNUkXY3t3m9NkzHL14md/9/FMUI8Mjjz2MNRU3Lu3TLXqGscZYASrghUcpS+gDbes4OL7CQ49e5N//D/8q//a/e44u3WT/9gH/6Y/9AB/7lX0+9DM/w2AwoO0PiXZOEmdJ0SOApDRCaIIX+BCRUqCtRkhDApxPeB8YDAYYYzKfRr7B5JMTllU7YqtU+JWnDUu2NobMpvuMNixaGVYrR9cbRNA0/RmUaDFphRu9zO5WdoVQTiBmD3D/N7yJ53/rd/Ff+gfUE8u59HtcLUouDN6F2N7laPR5/I3/kSceOEfauZ8ro8dw45/l0rWvcPj8R1g2n+asvxchHTcXz1GHTZbjMwg15KnDCQdHS27c3mSwfZ5ysIMxI5IwZPzHoFLHUN6krnYRscYGeFBsMT3/AM9/WbIxHrK8eUBDyXj7XqZxjN2YMJvBSIGJsFtqujilngw4poNqgzp9jRA2MOYihMjR4gWKjcBcdLC1y+7mJpOhQI5vcVg1PD1vOLO4zSBuwbLAS0EY9rjQEz2M6i3srGTb7qLckM/8zmXGjwwYlBWh89y+dpvmqMEoiVMrymKI6y39IlKOJ6xmS5Qawjb83f/lCR75+hWfu/YbNMuKLgZs81nufZ/gR7/xm1lMBU1zREX3mdQAACAASURBVKJAtjeQUqN0TULiZCBpQVltkFRi0TVoBUZXpL5iMnBoPDIkKi3fePLJwUdKu4mgRetA0yyZyRWDUYnUCe9AyRqtNN53dH6J0jDeKDGVoSgjhVVYZbn0pTn3vWXC5vbX8fQzv86ps5s8+tY3wcGzfOHjP8GDX/d2Jjsz/PDzPHf9i8wWisHOe9i5eB05HGIvvp/d7m8gzi0BgUAhgLnv6Po57eoArzzVRsD0LVrtU+kVRltScmhXooxiZ2vMqV2LBI6PwN5/im++74eoHzrPl//pP4bxm+Gh9+Arw3f+xe/G+EA/u4qbjPFFyXF7E6scRXeI9AmhDrmxqFCyYW/7Kn1X0XUbtDPDvY/egxkfIdH4xhCLs1y/ehk7tKzSHpIRAEI6yiqhVERVgetXv8gDD+ww2Yw8f+lp3v7172Y1n+Abx62Xb7E8zmNrhS7QqoXYomTAVEuu3rrGzs4OBweH/OR/9z2cu7jDzeMXWMyXNKtEWYy4ef0mg0qTfKLvFaLUpJh3jdzIybuOFFlU9UTESK05N4vFkrbxbA41QgSEAGMESr3BuCghRNomMKgMbe8gRcq6QKmEkgapDKsFNK2nbTwxBZQ0aKMoK0FZBMpKURhFUocsvaMXigv31Qw3Eoh93vMt9/Cvfv7T3HjuCptLyT2nDF3vEDqy6r5G36yo1D2Y8iFeutyyTBNKU1IWBYWxgESQOF7eztRQWWVJX5FI0oEWKD8BqZFaMixqxrVGSTjYX3Fr1rExqXnrt70fozT9YsVBB+c2Buyd2qZdLXBdj1IFB8dzrl25Se0NKjqSUIz3zvPQN7+Pz/zGz9KJnlvzKd/xnT/Mez/wfZhhxz//0N/mYH/Kzs6DnDn/bs7cN+XZ558EdwVCpF11rJZTRGyw1nJ6d4+RGRJcYnbU0jWK6TwwYMpiOmVxuI8SirIoMFKhxATncmfZ6BFVNWQ2TSyaggcfPcWqPeK4P6aqNkmhYLlo0LIiOEHwEe8FsfW46KmSzuNp62GL7OyRnYyFcBhjSVGRUlbgElkFKYsYaZGFOF/j8bpY4CCYzVYMqhKlA6NhhbUaH3qMMIhUMpvOWa56+i6QlEYaTWkEpQkY5dEyolRi9+wAoTz7Nxvmhws2Ngdsbxeo1PP4u7Ypa0kULckPWM08uixojhZsj59j52xgUBa8rDy/9HlNYcfU5TaDagdJRMiezimM0mhdIoQmKhBKkZSkdLvEBCn1KCUpDRgDp7Zrbh4ElrNAPag4e/9bSK7lbH+DRy6eR4qGZdMAJVZVLFYNRzfnDOMAEQKh3qI89wTf9dd/jJ/4rz7Iz/zz/5qPffQLzKozfPjTz/H9P/AdPP7E+/jNTz2J3XuI04+8l7c+epZ7vvrr/ObHfpLYQVEoKrNJKc6ihObFZy4RU8fG+BReQb8sUPIUh9e/wGq5JPUdyg4yZTlIOg9GDzFGcXt2RO8F88WUohrw4COnuHTzCkIbZtMF3iVIAqNLcIEUNSKJbCDmDEK9Wr4CkSkFShkSAa0twWeZC2slQkRSisT4apmL13K8Lha41pq+8zRNx3hSUFSWPizp+4CQAiJMj3q63iNkoigF1iYqA5WVWXVWOQQeU0VGWwqhDd4tGY4Uu6cmXDlesH1BowkIqRnUExZtYHqwpCor9jYbOP4K0/As5069jQd272f/1rMcXE3U93wTw+1dQoz0HlzQuGApqgnCCryJRB0xgLQQdMSzIgmDTAWGDlYd2gwhwcH1A1w75eseOuKBs1ssFy/jhEWaIcHD0bRhdvuI2HgcFrF1Frf9OF85atnoNnnTW/88N3/peaIvue8tj/DiUiLq87jiZW50JTuu4nQ/oBy/maIomM6WSCyFHpO6gtXKM7RbXL7yDNevBSbbWzgvOT54ie7qci0AtEHoBcs2IoSjj4nBCLxvmfrnQIPdg3e+6xSL/jr7hwecubDD/Np1og/s7Z5jMVviQ464QqtsTCsCSXSAxCeQKSIzhoALESEtLiRCzDIRymqge1VR/QZc4IJTe0OUFihRcO3aAadODWgbzfwIVsuW6bGgrEqKIjHaklgtKDVsFDajL/R4EZjsKsY7A3wruO++GiMCxI5TWxts7oxYHM1omzmLbo7RQ7ZGQ1wDyyua0ahiaBXHt5/ikc0vMnnTeeryAi9e/iQuKTbPnOHFm0vmTU3bbTAavYN6MEKaSMBR2OtQjIjScNjUDFcFwzLQ256ds3B4tE/XRN768L1MD6/z/Jd+i+7gAPGWc4yqEdpucHj9EvOjfY67F4gjx9be/Tzy7d/P8B3vR75ph5fmLb/+8a/ybe//a6QLb6E4tUs3hM/9zgs89uh7kacf5G3f9jD7z17iyU9+ksWVcxhzwGxxnZdvP8PsKCElPPzoiA/+6Pdy/s0eYyWPPPw2/tJ3/R1uPg3KgC2LjNoolTvM5ZJDl0gJfuPFH6OJL2PqFcezG1y+/jyb26e5dbNhd+csi8UCQXbpWHZunVIKHHmGVtk1xJk8IXBHVHPaNdSDkrZd4ZyjKArKUpOivgODZtj4DZaixOjZmNRcvnyFvh8w3phwfNRnX0yvWcwdhR1idETKnkEtsVpRKk0KHa5tCTiCjFTVBjEZvMxClEImjLVUbkU5GCFjhTYJ17UEH+j7GdqMaKMm9JpaDkBYjHmK+ewFjg4PqAfnQStCuMIjD51jsWq4fu0QrUuKOAKXKEqNdwN861D1WVIcM1sAShLViLY4xG4PCV2i8Q1bZ+9le/zDPP/MZ/ntL1zmwvYIzVU2z92DlR1oT7W7TbW5hTGWg8tXefe3X+TKp3+LF778JN/0vofQdYGuJY/dv8nPPP1Fjq4dcP83TpAd+OOX8EfP0ix6Xnj+Sfbug7/1o9/L/u1LnDq9xV/+/g/Qu5tEXiZFx/Hii/zyx/8+V57q+fkPf4TOK1ZN5PlLV5kue+576J3M2kOe+Ka3cunWFVbuGhs7ipAESpd0LWgzYr44RkuZDQm0Zlhrep853ilppNQ0Xbee6FdIlTuwiYCQkoQioUmE3HGVgq5x2eFYW2K8i/2/luN1scClFMTUU9gBi7kj+DwIq5WBqOm6LDATYoclYrTAmIRRCYEgJohRIKPE+5RPTgKp1rOGQjJWDb2CvlN4V5O6EhEzFpyEoLcOrwQRT/ASJwS+9/h+geheQhURU3h0c41BeYr77tmgX+nsPBEFQ1VT1qeY9VO6tKKdPsA0lnhfoGyijUOctyQHqi9yN1/tsXvfiOd/65/yq7/0q2xZzcf+zS8wa4/52uc/xb986kN0R0sOP/MF5G4ifnTKpU99nMNLX+bp3/4U+qilPn+G5sUVh5e+jG8ucfm64cWrtynmn+fB7Tkzc5t3fOsmH/xv/iZ75wyNO8/29gbz5Qv08Rj8FJEERE/b7LP7UMdf/zvvxtgdtJpQssWV2ZSPfuKz1OPH2dyZcNxcQ9tNFk2gaQMDJBFNxKynhjxCRqyAKDwCT0yRFCSBhNUGuCu3J6VEKUMIjuBFloeQGik0KQWsLlFK3ZF6/pOMWb4uFjgImpXDFpscHU65dq1BqxopA5MNizWWIOfUZWIw1Jwa2/VJ0XinUL2k7XKFH7wkERFBILUFCVEpCipE7amKBjEMGLGBW1ii83gC0TQE2UNwpNbQmT0ShiAlzaKHpUMZh+SYXs4BRb/6PCFkaYqFV/iwRA9HDCankPpxRLeHPjqNKc8zXJ1nMZeoGLi4OcMw4zgtUMz4vv/4fbzzwR/hPjukxFHVS/7ej/w7fOoj/ydPf+lLcGGHnXPvYM+e5skXLrFRTPnKZ34Fs685/1bDbf97bNURV0zwYhu1gsMbX2LnzZr/7L98ggtv+QYW3ZM8d9BSlls00ymrxRLfO2QosUIjhWCxuk6xMaR1ntbNQRiu3jzgyo1bDDZ3UJuK/e4YhCcsPP1Ry2AwQoliLXqaef0pRlwKIFdImSgLiUoKEQwhQQpqnXMHFBItBEZZQhQ0rSMlTVlpTCFIwr9qwCElzxvO4SHFjHP3nUDrMa6b0gSBEo6NjRHWSrQJDIYl9UBSWUVEACGPNQmFlIkYA0bpHM1FwotERGTjuVASOUaYBisdcqyQFNlJOQkKWSBQEA1CFvjUoFSBUBZcQd8o3FKQJgM8Dq0l9UjkFMm3tO2Cygxwqzk+zjHLGYXdg+IUoj/LxdPvJO0aZGjwR59kNbvMbBURheHmrUf5MjeZbt7LsD/i9579NQpxzLu/+QFuLF6E7QpsS1VOqKsNfITNnQliNEBrzcZoj0M7piq2EXsTbBXYOl1Tbkb0xHO0Oma8OWE+n+H6kturNssQJ5F1SJRE6URMK27dSAxGQzqvQSqSrqmHmww3hvjokFqgZU3nG3RSpNYQKlAikgg5nw4ClRJRQ2EVQmlU0vRtFrEPLpISazvAXDQGn4ghz+Zqo9e8d4hr+8C7gqFvxAieJMSK5XxJ8JbeKRYzR1FlX8s4jAxGkmogKSuNFQqfIn2MxCiyEqkUJKHQQhJTduPSRhLJM4iRgIgJKyRRScwgIpKjSgHZSWSqScKSvESUBX2/RAmHkppoJLFX9J1gcexBeIpSkeiBiJQGH2oWYRs7qBnoRJgvmTcvENNLFOMxl67+Ni4GjHTsVVcwLNjZfJhl1/LsUze4+uxTfMnsspy9TFVOqdQCLwPBN5ye1EzObkGIbGxs8fIKhnsGWSWSWDEc1vTecuH+8+w9dj/PLZ9maBLVWHPUTrETw9UbR/g+cfH8HkcH+yThUBI8iZgCGvCyxw4GRBVYLDua1jObrxDa0PXZtlwKQe88VhdYY+m6jlAEiOvIGhMkAymhJVgdSUrnyL5WIUtJrhmEd/k0WV4uu13noQZBjB4EdyzTTxCUPwGI8vpY4AnJfOZYzDu6LpKipWkXCJmYz6fUQ8FoXGJsQqqUO18hEV2gj4KQJIm1lFnM0FMSGZ2JUhIBFVpkMsg4zhHDaGIRGE0iahVpW0FMCRc9wnhqsd4hUkthJJQpNxi8J+ERWuGDRMkKW9YYBYuQ0G2+wcrVEBsTSkdmhzdZ1RFlByRlaZc1QpbMnENKhW575qsrTP1t3HAFzJgMFate03eCdn+B3Z1z89olCl2QgsVoQTHoMXaBFCXJ1yybFQdHzxGrlzl1rmLvzBhZRdoY6KNie2eXly9dZmNSAh5jBV23PochEYREiY6ucwxGE/qwpPOOyhYUpQESvncoIlYmUuiwKjtDJNlDSAihUdJitIbUEUJDin6tZ5KvH2GNgoh0R34uhKwpeSLEL0RmRSqdX5fZPQmtzRsPJuxD5IX9OdMbLXJN9Ty1XXB4fJvDoxJbbYDcYzB0FMUUH/YpyjFGV6yutQgRsCYRpcskopBzuujW6kiFRtgx80WLRKKMRUioRMDERDWCG/u3iZ3EakvbKYaDDWLItNC+79AGxrai7SJtLzie9wxGQ5S19OsIZJRCMaJtNTPfE1MPIVCUe5gQiAtogqBNGyhp0TRUVYW2hmVaMl8t6Y9bNkZjYl/wpsfHfO/WiM99+rf43Cd/mXOXh+iwiyxrzg0fw85bJJ8jLmeErRf52ktfYXP+azz67gvsbO5yywX2VvvY+gwKhZsHNoYjSq0JURD6jqIwmAhNF5DqDNYULJuG/esHLJcN2+MNhoNxnrSKEZ0MxuSZyJA8gZ4gRoS+wHeBUndo1QEtTd+RRE0SEhcg9RJNhSp6vPe0vUAoi5AW7xJ9n9BK0i891iQKaZBe4ou7LhTW6jcgTJgirg9ImVu4aX0313WN957joxlHhzVaBMajgC0UMUkkGmksEBAic4QzhKTWZkU6qyJFtR5aVjl9iQmjVW732xohBK6XLJYO7yTRJYxURBURPt6Z8BZAXVecDAWecK+VUmit8+xo/hY5EmmDlBprJRCJEqQQCCxSaPDQ9x0hBZQSVFVFCI6maahLgVBgK82ps3tIBpy5d0BsKm5eucKnP/cRhls1u/fUjE9JHnz4PtpVC0jKUYEyErfOV5VSBHVCsQ0g5J1zFZ0jJLVGLiSrZUfX9XSdY2Njg7quM3d+7TIsxF3J5RgjJEkKEUEkiVfMg5K7jnc+J7LOq7N0s0ChlMhdYATeuzVS8mrdl3xCTxS9Ml/lzxQm/ENc1v4+8DeA/fXLfiKl9K/X//fjwA+Srcv/k5TSx/64z4gh0rceIWzWCo+AT1SDEdPFEYt5x/SoR4k83hSLgrLIkSRgSbg1VyEvJACZJBoNEaTLBHuRrw7BebRIGKUgOJQxTEYVRmm8E1Q6EXuRi9XsMrg+4RFjFLWq0EZxPJ3hnKOua6qqousyy+2O3jYKIeIdsfoTlIfo800hE23fIJPG2pKqKug6Q3AOFzxKSapac/bCDhsbm9jJis3BLoO65Gu/e4M+LXH2mNvLnkfvfYiUNljOVpQjS1SRPjhAZuaeSogIcV2wpZQ3/ehjloRLGlC0jafrcsGXRToFs9kMREDKLJ/m/XqoIp5ojOcbAJEVqCJxTYzSiJxoA2k9NK3u+HkqlTVWsqBPz6CuECIRgkeKSEgJQW77n8C93oU/8yLzn/H/dlkD+McppX/4yieEEI8AfxV4FDgLfEII8WBKf7SpikBgpCFqTUzZ77MYWJCC8XhC37c8/+wx7Zma1UwxGJdrmLDH2ohUAaMkRhcU1uYLkTRWjUhekXpFxz6lKfAi6/H1qwapEtZqSisoakEpwDtoZWS2diNzfUKvWnwIxCBo+4AyJUWhMEbTdR2zWR4U3hhNMMYghaZ3LTF6ggsUpc1RK8Y1cUihpECYsEaIEkJ2SGk4XW0j2WCxOCAZRzFKjElMdkvaomW04bj4+B7v/f5zHB3PuXJjn8XKUVcjUlSEMMRMEkF1OB0JSRNiIoaESBEpHDneZsKaSBopCqLQzOaOZh5YNS1nz50lBIfzDlskfHDrHTbS94FMIVFIqfE+jxUqGQkyIlKuhxIyIyJJgI/EPuTdOWUUhZgIocf1nuQblLAQA953JJ9IKhGNwpiMcCXkmvD1ZxjBU0qfXLusvZbjLwH/IqXUAS8KIZ4D3kUW0P9DDyUldWVxQZI0xEJQ1RoXPKUqWInAwf4RViekHCCLgpgcSkdqslpTFkbPuYTVggAYGYlREZwnGgXSokwirn+2EJG4Foc3SlOVGlEaBpWkP+pJKReq5SqnPN4DSdM5h/c9o/GAylUsl0tWqxWFqRFCURSKojBZ21qkPGMoIlIBIiObUiSUVRgrMDauDXwDg9KSgiAEi9IJrSV9DyIFtvZOkUJPGxeUxjDYjuzKiknYYH6co67VBbJyJF3kIJEa+t7jXI9WkuIk3VoPLHsvSUkSo2C17OnbFSJFysKwXK4Q0jMYlqyaPg+drK+XyG1GBAKRwh1EZP3uuSRMYt34WfNHYiLiSdwdnI4+C/BXVYFIOc3JqdCJ/rnKe/JJSiTlHyga/Ycd/19y8L8lhPhrwJPA304pHZEd1T7zitf8kS5rwA8BVJsldSXok0QJTYwepQM6CozRaD1guZQsm56mrRmEE6PQSECRfML1oBRoKQk6IaQnKUfwCdcFfIqE9ZadEghpkSJQ1RVWK2Jw+XkRSSEwHGVjVe8SbefRWuN6CMFC5xFdRGmNMZnOqZQiBEeMhhgVxkqkFEiVzVelFMiUcWAlFUolTCHRRmDL9UVFUdiYOdjFGFMqtDTZg6gNkDRJ5M8NIlKPBngSbStYLhNCJZCR3jnqqsAqS8LTdIHoPbLQCJnTuGzUJXBuDdNFwarpUTjGGwNC6BAy35QhBLSy61nPiFIaJbNe90maIhJr+rBcoyPZW97fsVzJOLlIErFWuY0pkFKPFDAajXBdS0qgtEYriVm7OaSoshmVEOvPfu2L9E+7wP8H4IPkltIHgX8E/Ed/kjd4pcva9sVxKossDqyEyLYcqUNJQWE1VV2wWo1IdPQ+5gZBDAgT8zByDASvCD7RmkQgIgkk60gh0vlIHzwrYrbfE4qq0KAEXQ8xBOJ6C7ZaIrWgMtlSw5tIPcgR2BjBaimoqgJrBatVngqvqoLhcMjRrSMkWeZCJJBCokRiODgpnu5Ohysl8ElllMc4jJVoHZGxQxhJVdVIEdFCY6xluVyxXLYIAVpkh4ZTpsKYghQ9uzsVzluWq47F3FMPSnwfENbkvDUkks0LLwmJVAoRoO+6taKvxblANUhsbtX0rsmLi7T2HMquyie5tCArTUVS1jtcF4cR0EKRREQoTUrr2iOELI0tIQmNkpogs2uxkpFBbZmvuUNaZaREq3WenuSanJXQyvz/j6KklG6ePBZC/DTwi+s//1Qua1JGdnYCIRqUNkiliGldDKpI8I56eIq+71l1K3QSVMOaugZte4KRBB8IIRJI64lsz2yZCVsxZE0+LYtc9JA4nq1IsacoFWWhqUuz9qtpKG2F8P0dQyulDErlAsqHHh9lVlkyCinVunhKjIYG5xuUlpw+s0VR6rUMQm4OSQlCKopCYIzi+EhmIthArsXeYVzXGFPivWe5cCyWjqPpkumsZ7OIKFMxO3Zsbe4iY41hijItVvbMl55GCCo1IDUSnTSuSIxGNboMpNjR+4CU0HeekATG1qzmK+aLI7Z2ttidHFPXAbGKeBexxiKMpW17UpCICHYNE3qfPS4HdbkeXAjE5PARlFT4mMt+YwxaSDwOay1CWJRSzGfHSDxVVRK6JXUBWpt1UZ6yuwOCpGRGn4TAxZxWvtbjT7XATywE139+D/CV9eNfAD4khPhvyUXmm4Hf+ePeTwooCwnKIpXORqZJEJwgRYfSEiQUgwrVJprlkvFoi/G4xqcDErmR4Hqfq/QEMWp8L9b2KAEX+zzgCqQo8b1bGzhlSz7v16ZOIbFSYh1lTSYBeTJ8GV/pSibXZK6IUgIpBBuTGiELilIidYctBaPRACESzreUlUYpASJQFCZfNBnRxmG1wpi8s2glaBqPsQnT5ujXtX3O4TEgEiHlYlmrgFHZo0cbkR/HSOoFXoSM2iSVBwZCriN6mclpKQKIjEm3LXunCk5Gyf4gGTghJEqLnB6mkDk/MpLC3Xb6usAAmZs3cp3zZ1AgC7IkxB1hfqUVSoASAWUUSp3YiwukOFHEUaSYI7j34c8cJvw/gD8H7AghrgB/D/hzQoi3k1OUS8APA6SUviqE+L+ApwAP/M0/DkHJR+5OSi2RWhFFQsWEkpJ+1SFF3qKkltSjguWtJV0fCV4wGA9AdMTksr1FlHgn8S4RtSR5D0pkremwxm1jzDisgK51WYdj/S1TEnmAWeZFbozEOYV3Au+zRqIUmiQyRislCJFA+DVXRlOUkun8Gs5HYpKMR2N6F3NTxUp6tyQmx/bWNiF2RN8gVcQISewbnOgheFLMu8SwtiyrvBPE5BBakWSkcx1SRJQEKQJKa1SRv1OMEd8HnBOQdB4ckR7vWgSsrQQlnYsgBWWl8WFF9ALfB1JYY/brulGSEHINtYpcS0gBqDy4ENJd7DpmYUl0+fsKwpgI0ZOMoGt7lFKUVkHKtAGtJUqITI8g5/chRlzwr7JN/DOFCVNKP/AHPP0//RGv/yngp17zNyAT3n0bEUhSnxVQhcgi6DHmKOFDTzdvGWyMqbdGHC8WLPsFDz28Q1VKjNFYW9HOPEFAkoqxSrg6t5cdluXc03cOHzWlHiCkxHufHcpCTkUQklXbQjB0Mgvx967nJGiUxTBzX1IiiYxvs3ZeMDagtGEwrDl34SKLxYLZbEqzmnHx4r147+mbno3JJkoLlsdLCD0iRFRSufkTE52bU9YWmVZUtmbv9JAQBKtekESk2jCkomfWNghpEaIELTC1oZQBOfeEVoITHE8bJhPPUGmMHuD7RNclqqrAmIL9ay/S9g3jzSHFENrDkm4lUJp1oUymvsoApDsFda4nEikKeq+I3q0bQpn/EyO4ZYNVeZGVVjMYViQfOF50tL1jVEq0FGipMSpide6JJAEiSVzKZghScmdxZ174G2zoWCCQ2AzpxUQQuTPY9Q2VrRForF1b3QXPxrCkUQnnOvYPZkwmmo1hxpajC0SvUVFQWLAy4GSPp0YERS8FISqEsAihSGWJ9z0+5OLJR4HrPFKsU5Pk6V1acyQsrHN4KSViTdZHZMVXYzN60/VzjCmpKkPXGWbTJdPpnLIss25Kmxsjrm1yaiE0Go1i3ZBJBYKAsXlr121ASIcIe3g6AgpHRww9Y2qkrJFGg4yY1IPKTZLgE8bDctkghaGqJFLkdKXrAqvVHO89ZVlQlpYQe2SqiTHXCymS2XvRY4tc/GeFrRxBTwQ/Q1gjSClirDlplOKcz+hJjBiVYckkE87l1vvJlI5UAqPWsnMp02XT2sz3pIt5ord4Ykf+Wo/XzQJX0uRJDpktNqRUeB+xQwvJUEQFKbFyDabQCFWxnAcOb08xekhdVLn71UNwYW0mGhHKI1KgNAaVLN6oPNAQijuSzH0vaHpHQiJSwPuIXp/ITAIKa4ZbHp1KIrfRlcqwmFznlkWZcfO+XzCfz+8ovE4mE65dvcF4PGYymSBVVgYwIqLIW7IUGoFBkJCyJ4QeoyXK6DUNIYAYsE6cidHjvCehEKpAKw0qIIMDIiFGklfIIGiaBq0CUlkqm2/G3KCaIZRka2uLelRwcHydTbFJiicd4XU+Lhy10TjvCDGQEOu+QG7ph1BnCPHO8IK6g/8T+jtsweRPboiw/g150Qr7audlRMoDEhnPJQSXd7++f5Wa12s5XhcL3AvBsQwoMV0XKtBhsZPTHIeA9w6funXOZll0S0pbMZxsMT2Q3LyZ6FrBZKzY2PCUwiGiI6QBxL38fuImg52Ktuno2oSOm6SoSamnKKH0nmblaENiZzDm5qLNuHPUdK2lTdCsIkp7tAnYQmC1yZ1Jn1OW2SzzUpQacPN6QuqEEAVCKUxtmPeBxf6MwSDDe5XuMEoRo6cLHVIEhgOFEgnXOrQe07YRqRXjScH8OvoU5gAAIABJREFU8BCrBP08MJQjDBl96dP+eicoqZSm0AOcTrQhslxJ9DAQQkMIniRHEDTLNrLoLeNBjTUj+qVjqPZo4jWEEWiTcXyrJFoVKK+IThCcJShDRGZjAhPQMVv/BR+JTURqnVmSUdI0EVNWtCFybZq7w1oKjCpIoc9sSSze53RRiEEGeSMEBCnGXIiailLa3IV+o/lk5gh+F9s86bIZddeFNzh3hw+sVcT7lqoaMRqNmB4fMj3OfpJbkyFC9MTQIkwuclxySFkghUFrkafeu7worTXI9dCysYIUJdHnPDNFCCec8/VgrPM9OgQSuQspXyEjZmSmtp9EG2VyvhhjZDAaoUKg6VqmxwuKooASvJEUSpO8QyDojMjUVJmV3npPNuVSJjseSI1ayy6QcnFsTUlMLTHkbmbeaRzeRZyPOAdtEymsJJQJ13Q0TcN0OuXM3oV1cRiwNhsMnHgn370g2UYcofL5S2Red2QdqfMgszAKqRRqLdTvXE7lQkgoJZkvFjmHNgVJRIwxKAlJ5t0ghCwZIaXEh4APIX+LcNc+0RjzBkxRBHfUjMIrXMNeTXK/u5DKQtF1jq5bMhptEnxPu1pyeNxwandMWShiylMi4EnCk4JdQ2YmMzFCyDkma/cI6TInROTupbUa7/ICSimQ1u8XYu7mSSnxDrQRd1rLxhR3CiIXfF78OptoNc3acDVp2qZjMZ+TRgVFAZQGksxTMUmvW+tq7awQiUIipMKHPosOrc9V9Im+dzkHV2lNmJIE73F9pG1zfty1mYftqkQM8k5qkXzAGIXrW7TOEzZ1VRGjR4SeSMKFgBCJKFLm+GiF6D2sGYKCnC6ltZellgJl8vV0voOTm5H8PUSp0CYzPo1VmZiZ7haRmR2X1tNBgUwjj3eC3hsyBwexbhQkpBB3YkfbtrlrJcAodfdHKodSuSARAgaDAYRIs1oym3nkqIQUadMKbfLN0neJvmONkbMWk484l+G+mBxCgrUVvc3NCQh4n/PFlFLGl5MgxgxDep8jl9ZmDReu+RNyPfCsTpi1glW7QkqbRd2Domt7bvctpU34kV63pRW6kISYR7+0JfNzUEDOQ/W6sRSDoO8ji3nP9paktBXeQXCJbq0A1jYOsf7tRoN3guRPfkPM5w3WJrE288NrCUheCe6eMClP7FPusCVFtic0Kkd4HwMh9ojAmkdyN4KnmH+HEAWJLg+oKIWSEEPuSaSUCCTkOtCd0G5DuGuT+AZd4HnU6SRqkxKhzxEm6rvRPHO6JTFIBoMKLSWr+TESRT2oqIqSGzcW3N5v2dysGI0svnNoI4hJsVguc/s5CZLIRaKPHoUgpB6pNNYq5CqPX4UQ6LqW3kEMihiyLUlwgRgiUjliBVWtUMqiZYfSAqsl4/+HujePsTXN7/o+z/Yu55w6tdy1u+d29/TsHnvsGY812DDYMI63BBvkCCMBdgYHjBIHHCuxAQmk/BVIFCRQohiIIuPICYmDFwxe4gUzOMYmsfGMPe5Zeu+5ffdby1ne5dnyx+95T1VjCHciIt15patbqjpVdc6p532e3+/7+y7VTBa3FtbdbN6QomEMUI9glGW93jIOI5vtKc45Kqd5cOpROqB0pGo8Shlm7QKla8bhmBwUqTZUSrE+S9y9c0pt5yz2G2KA9Tby8L6n32pIc8iG7dmWytZsTuHm9h5tU7G/mLO3aBmHLcZmxn5DO7OEURAOs0txE+KU0gqfpCaaShKrZdNxNITo8SEQsifEQEhGHHSHRMqGzWrAmD1irNC5IwZJ7EgqE1IgieM9IXhiDMLbLwM0uyPHfT40K7keiwWey5DAoAFFRHbLyaYrIawzVaZijZuh0ZDl6M0xEMlYVxG8+PA1bcVyf0ZOPTEKmUl2InmTdt0+WdCQIMy3yapAILCx/J9lihkzzjbCrwgRP2acU6RU7A1qac6cU1QzJwMgQGlLP0CKQh4bekEV9vZavPeEQUbTMUEYIsYmUImYPMaAqyArSb2IZFJU5GQJXtN3kW6bSAyQNV2fCT6jlMNZR0yBGBVEhx8jvt+iSBwsZzjnCKGjdo5tt6WuGtRu4CUf+BjIORd2ZN593ijho2ilC+8cnNUiFJGxkLAUCxrSDx5rKsacsYUfnsrZlNMFdiFZ6LDaCK1CgTV2t2t/vsncj8UC10oJV6HUYeIDLqy5qe4SnZ7aiVpzEuZcXTuiD0Lo8YOox09OuXf3IfPFVdqmFtw1iMG6dlp40FrtMNjT9QmzWUtdzxj7jI+y8CdIa7FYELwheFiv17Lb1o4QtoSg0BraWc1yGXG1xRhIeSDrqaSCum4I0eBHmHUBZyqqSpP1jDu3H9L3W2y2GCtmpLNZjbGaGBKr1WbHv+47T9sYUrS0zZLTkzM26wBaMQ4jPlpiVMSgZHoJOF2zWm1x3cilyxU6w2I2Y/Rb4tjRKc1i1kqShpLTchzL1FYbbGUKpCfiX7PDrAPBC//bOYdxNT4GsV6LqQgtDF0vJpq2rmjqlqTPqIr/YFYlUa+ACKKOqgUHJ2O0iCZiFO3nF+agR4mSOg4DKskdKjsEu1Gvm0gNMXF2OlBVlllraeeaUCnGfsCrSGNamvYy69WGl166zcHBkkuXD5m5BMpjS4O23W4BmVS27T7kTLeBFCqOH5wIyzBJGRP9pPi2tO0cazXaZEw10LSG2cIwX2iaVvgjde1wdbXDbMeY8H5EZ4W1cHCoSNnh/Sk5a97+9sus1iPHxytCzLTtAm2gsoZ6VgQUw4B1HdFL3Mc4RPyQ8KPi+OGamJtCftKEoAjRk6PFWc3p6Rlto4kuopLh8GDB/Qe3MTqz3LO0TYV1iuh7dDIorWiaptBoI10/4FPEIG4FTjuJWM8ZTRbbCZXRKGrXYE0mJA3WEVdnWGtpFzUxJVbbFc0MhpzQOhQeiqWuDH3fi3YzeomM1EY45GlEa03btkwxLY96PT4LXBvGckwZFBgtnTVCob1IkQw+YXUkJV04wjKqV0rRbdZUruXS1Uvcu3+Xuw8ekrXhycvCx4ijl13VOvpupKpF8aKUkK5EOteglJCBFIY+qB2SIq6yGaVkJ7MOXJWxLpOCxyupT11V7QYZTlsCkZwDGYWxGoPGOcM4BLTOLPZaclbcfOM2i8UM67Ts4ihSSKicCuclktKIci1V5ZjNG+HBW9ltVcqFX56IKQjFIEWR02VFVTmxTEtC9BJVjYeocY0jbHtUlPm63KAQUvlYayotO6hWGVWa1eQVKCUzR2XIGjSabeelKdVIX5U8SUkpllMm6CiojFEYbVDGoVIS5CQhP1MZIO5OclH0fIEtcCjYN4o8LeTCE5mUHLagKDlnFIJNh+I7rTRFsGoYh5GUAymNHBwdcnZ2xr37D1jWS5b7LV0nw4ZZuyRF8fwexxHnHDHCMIw0zZxt8LJolGY0oYzkzyHBXOp/6zLGgLHFHDJEkjbFgkxShoXYJFZFQimVP5DTiaaydMMICmEYas0wDChdUVsHORIi1M4ymzshglmwFowzLBYNOQ+0M0dKERMjQ8goFRl9IPVyI/kQUEozm82KRbEICqrK4TRAFoldjMA5Yy8XGoJGmJASI2LQKkofRGYsjxWPQS204hBZrTaAk5stelCS2pazIinhk4dYOEha2JvyWOEQkjUYg9V2h55cnIQ+yvXYLPCp/qI0gVmfg/pZHrB7nOj9IjFCCFLzaqOltlzM6PuRBycPuHz5ElVVcfv2bd64eZ9Ll9+xW0Dep6IkV/jCEozR7Lw50o4aK6eHsUIsUoW0rzQ4J8Me6zLahAIXSqMsjZ5GKY2EgpWfo1Mxv5HhRlXPUSSGcSRlx97ePn1pBMe5mM87rdBtzf7BrJQGCqMTzhhm85pu21M3yI7nFWMSUlTuAzk3WFdhBqnrZ21NShuUCiithR+jpXwb+65kq2VyiiSlyOV5i89MsUFWGVucp4zSRDsKGzPrYrMR6EcxbTLOMsVyoxXaKrKX4jNmhS4R3TumpjaoBD4KXKiNwhQp4jlW/ujXY7HAp1rVGIPhPHhqsVjgvZcFGcLuDnbOonPREkbYMduyZPVoDcv9OevtGVVb8Z4vfg/ppOPTn3qZy5cP2D/YY7OWYNFh6KhqyziOpOhwrubOvYecrtfEUHBeu5DGJruilBfEZrEH88ltq1GoLPi0HwPbLlFVlZwMOVDVFltV1HVCd1tCCMzMgk034uyMqmoZhszRUYPWl7l/7xZ3bt/m6GCfxazBaIurI8YG/OgxtmU2q1ns7XF2NnDpygJjYIyBfW8Y+shmO7J5ULM567h0tM/h0RxjRD8pqFJi262xSk6gvb2aCoFRfRZbhJAQm7wsk8zpb4CW2YSuEIBAA1nhx8RmPbDe9iwPDjhdbwgkbG0JKTCMWyrbiJpTCc8+pIQfggi2rZx+/TCQ8cyVBXtu0WHtOaLyKNdjscAhocxIVVX040DfjdSzlkxAW8lVzSnjKoe2Wlxak0EF2HaByinaxlHVNSn0YDJ+9NQqYnOAfsV874jVi06+jwXKWPp+RdPW+NiBqlG6JUTFpltj3BG2Khk92ZKRmGzNCa5KNK3i8GDGYmlpK4NFM7KRoVHBiI2DyiE7WZTsR+8DNiYqbelGcNWMnEe878h4nLKkZJg3ilvHnr5fceMtl6gPjkj+BcaxKI2qQFA96/UK4xTaNnKy+C1zp1B+RNcja+vw5iHZ1hxebUisqZwmJ9FVVkbosEbLGu6iK0O0AaPBVYYYM+vNiI6GWDm8rfApMKBQI8Q8Ay0WendXD0lVpl3sMcYRXWWqmFAxc2BbTGXox46sNT5AFyFlg61mZFuTcyKoDbapMSqT2LDdqsLxMZ83H/zxyKpHJotTZstklTu9KBmB693XZMcPu+/JuWDIQeDCSbwgGHok5sRqteLylSO22y1vvPFGCR21haGmCo1UOvSq+t05jNPz0UUnKFChNFxKT/isIBwXUwgunqhTQ6w0RZh7cSp4/rq7TnJ09vf36bqOl19+mbt37+6+fjE+cJKKhTCSs8jRnHM4W+NszWw2wxjDcrnYNeoTamXMOYvv3NxymhcU7U2hSWglxkbjOBa9ZEUiF0G1/Nyu66RfKgOgqVbWnL+2aWg3lRsX48inr09Q4GSotFsnF17zo16PxQ6uYCeb0kVU6n2k606wrpY7N2a2QycLwVmIiRAyVa6BYkYTMlYpjBUlzm4ymgI+ROracOPpa2w2HZ/73GtcvrLP4eElhqHj9HSDHyJDL2XGNGRSGGIRRRibymmhWSwd7cziKlDaiwtqRGRaWnLbc1YMwYseV0vdKshXIKW4o98Kkd8UODCyWMyIAfaWc5bLA+7dPebVV1/mibc+QVU1rM62+DFTGXmePgwoHagaSzKWoctsN56uCxidOdjb4+q1KwS/Zj6rJOrFGVQWxp6Ige1uyJLRxBSwSjg9FHPT4JOgUEZ6j5wjMWVCDmy7jk3fMWtblDW7iXTtJE5GZbH3SDnslPo5m0J0K31RDCgF1gr/xShR42s+/+iS6Xo8Fni5i1NEJngx4n0oapvznXzasWsjEz2xeVBFdV2IP1ph0SijxB+l7BT+bKCu52zWa7JSNLOWm2/cInG58EZqYooMYxKxrNNMmepCJoooHakbTVUrjE2oMvYT/kkipgpVkIVEKWIBzHmimFLTVPXNXiKTTZnWmuQ9TTsnpkgMCVcZqspdIPwXhCaC0RYP4oOITFS9Twx9pu8i6+EhB/s1KQnDcX+/xQ+paDIL3GmnE4qdjjWhiCljUgIkCU1oB5Z1t8UFQ90YrHP0my19P1BVFW1TM3qR21VGo4oinqRko8hZwAMlGtEE5QQKaKTpt0YXeZwM3HRZHxdPvEe9HosSBYrOsTQw3pcXrMouqvSupJDjLKB1EtVJKStyEr5JThSNoELpYo9gFAdHB3TDlkSSyVzOaGt47fVbPDxelWRdQ4hpRw/defBlD0rguaZ1VLWirg3WibRLm8m3T3YrtBWhRJLntqP8Ji8Lv/j8XVzccmx7lMo0bYVzpiiNRtq2Zrm/YBhkHK8wJYZvskODEPuihomFASnMydXpMW3rCH4oWsq0WyjnU2Mx8UniyENW52qbkLM0mlMJhkxaQwhiVqQ1Y/BkhJkolhLFDqJIe2QmFEn5nFprrd6VSBdZo1qX8q+qSpNe70qXf5lV+ijXY7GDZ6b6T0SmIQS0rQTXHr1ASNrivWyJo+/LG2no+5GgE1VhAIYAykesizCzZTeCMG45uHTA6qyj70eMdTSzA2YLzcOHD7l58zWWe5eo631OTk4Zw7ZgvhoYcVVmNqtpZpG2MSz3Kw6P5mQ83g+EkDC2ltcTA/04FHRC6IVDGNAJnFFiUqnkZFBaQU74EIg5U1UiGduOZ1y6fMh61YtqJiVOzjoq16K1JWdp/lpbYaJhNmtpWsuYI95nhl528eC3HOzN6IdT9vdqVmcPuXz5MjkmAoEQI0pn+hAwKWP1jKwyIYtRKbEYFyvLEGQ0P9ubiy9kGjk922JVZn9/jxASw2aN0Q6jNX3fk9M5B8hYgVC9H1DW4lxF8nLDNU3DptvK1LNxUMQOGbXb2ISZ+G/fm/D/9yuGxHbbM5/PS7OnyGWX8V6I+7PFnPl8jlKGcXwoaQAxCq1VGUYfGX0Wx6jKknzGr7oybdSgDKv1FuMcTWHyaS2OSVeuPMVrr36C27fWXL/+FHWzR6MbkUrFEWczbVux2GuoqiRHszV470l5LBwNSS4Qe7ayO2kZ9U/U1J14dugwxlIVt6ipsc1KCSw6Btp2xmp1Rs7QtuI7srl1n9nlPayVEy5oGcs75zDGMPQeZyvu3bvNcnGd1155ictXl8QoNsnjOLBcLuWkyLJLLxd7OKeJyaNUKq8jIvWSuF9pbfFxxNkapRN9P+KTIcaRrt9wdW9ZmsLM2dmAcorKNTu3L5D3YUooDmEgxkDvPWPIZCxV3eDP/K5vCh5McbO1td2JSC42pY9yPRYLHKZSQ3w1BBUR+12jHVgZk08urWS70yZK/X3OJw9B1CZJRYzNOGdIGExWhJzkxkiZmA1CCjCcrXsuXXmKs9MN9x6ccv3aEosYZVqlmc3trqFsZ66IAyLDEJjSByTiTkzaoUiTc8bHsshz8eabSgKVdjuSuLPKNE+VXV8Vz5QcIeMFQrQ1Wlu09qQ8HdfCyR1HT9s2GO2Yz+d0XYerLIu9FkWCHNFKhBzGGPqtNOz9OLIdIjF6lotGuGxamJWCQiliEL1lP46SUuGsbDzB77DxoSSnVdZBhuAHFEg9jS7hr0WDqbN8Tk0BZKqIn8VUte9HtE7UzlxgMX4B52SC+JF474vIVhoSMd45h8a8l91Aq9JkJbEFUwULyHlyLo2kHDBOS12OokoyXYQgY3TxliClyNlpR1PPiXPLZn2Pvu9p6riDA5UKoCKuctSNgZQIYSTF/KbnjwolNigXWdlU44r/ttS2hY+e9E4kAWVqWpo5XUbnSsXiJSh1+zTZnRryHXUha85OtzhbYzK0bcvd23epKstyMRfOiYpAou87ecIJjBH/8jDK+FtZQy5NpnZW5Ggp42NgKBi+VhYfIsPYozU0bU3OkWEYhTTlHDFkghdimzFWbhg0gx8JWTg8KaaywMWabfRebDtgdyJarS9MlPObavVHvR6LBa60oqrkuNYJnK3EDHK7RZdFPlFptdbEIRHzZD7foYobYyTTtC2yGzaQNNutZtMlmpQKdyWUsbIhZ0lXzslxciK147Xrb2EYPKvVKfv7S/aWSw4OLCiPNlEQEwNgBSEoB4lCY6qy4JTGWSdwWxT3LB/FxizGTIjnynZJLahIKYrHYgpC/I89SmtsMRaqG+knTk5OdjdoU+3Je6IMJw8HnPFoPH3v6YdTnn32bcznGq0C7ayStLISDRKimPdsuq3g4q5hsx3lvcsRlYM4URlN1mKlZ11LCIFhGGialroRJVPKvdx8KeGHEaM0tTUY4+iGnhgQSmyWEClt5NxRsQgqYsL7JMkbShy3sgI/RpTyVJyrjL9AYwQpGsdzroEuZCudJwRCHie7uxLOM5Q/Rhn2kLHOgTGYrEnJlXCjSCzTH++jeGUr0Vgq7chZJorjODKsNxwcHLDXimI+Ro/Slqat0UYyY4wSbvqwFVesnAT+MzPxoBTkUnjSYqEgO3PO8lih1ylyDkyyrlx0h9aKN8zEuVEqF02icHX6vhNsPhVylMzIqVxLjOK+dXZ2wv7BHkdH+6R4ivcjLgjeXDkng6CqwfvAyckZoicVy7wdRweEO5LFfMe5mn4MbLqB+aJmebAkJc9qfUpTszOzF31nTWUtbxIuww4JmUIKco7lJJbvF4PPyGa7EYNVZ8sk9ZxN+IW5wLMQiFJK5BB28JHCnENZF1QfUAFCfsoCVTPp98bRg87FA1DG5H6UndFai/ehiAc0fkw4J4MirTQ5+XJDCC9C6Yg2mc1mRcqW2VzEBLoQ/scxSDNkXOFIJGEcIs2kLlrTqVYWjbguC1ehlSzcXQ2vFHUtooEYEjmely8pZZqmYbvti5Wd7GqidhdseegDOXru3LnDs88+S1Vrxg1UtWM+b2nbinHckrNivTmmrhvmsz1SDigDw9CTUuHdG73bTUMKgswM4ktS1XXpd1KBK8WnUCu5gbTSu7+VM1ZUV9owpgK9pvMFKiecwhYE6nxJTNBpJOq4m/RO4/pHvR6LBa6VQpsIzhAShDGjbUOyikkg23UdmoxzGlRFV3z3dtk4xQ0rDPJGRK2EZZgNtTLE3LJaeUKQ4Y+QpiwZqWt96EhKYVzN2WbN/lxT1xVN23J4tE+MnvVZzyonqsrQNAbb1lCPpLxmzIl5dyD2ZSbRzMSbO+SAwkkwKpagIBaS2Nx1oBTWOqwzpARDV6yKtSp/nExIiSEOvOWwYsGChycKb7YM+gGqUSRqbr/i+MynPs3b3nGdzgd+5hd/hW/91rfyzDMd4+YSfqzp1plf//XPsGj2eeEzr3PnzgO+7z//HlJKPP/xF/nZf/Q8f+g7387VJ5fUC896M6DUjJPNSO/vsren8esNh+117tw8ZX/viNbuM7O3sXrEqBG3P5B8YBwS1rRoxFDTWs2weYPFvOH+8BZSSgz0BBVIQKV7wrAmxiz8GCUnU7fZYtuKGDUxSshveHS27OOxwGW+YAraIF4k/XZLymK5ME0scywOsrboAssdPV0XFdfTAGjaQc+78LT7OiBQXxJxAEz2D6KoFw54qdtTsU9Ima7rGIaOK9eWVLXFe80wbsgmFWN42G476rqmqufCvkuCfxs0SQuiMR3ZF2EvY6Yhk4gNlCo5QdYykiUBQ4sjV1bisuVoePWl16hUw/ve9X5cG/jRN36K+68dczBPzOuWs7MRreEPfdM3cvv2fd7yxFvZXx7xvX/+L/O93/un+Zmf+Wne9c6vYlYJo1AFTewzTTuDwdOafVpluP7k07zw269z7dJbiJ1iu91gLsPyyiW23UNyl1m0R6gUITlIidl8xqZfc+3Ks9y+cxPdFE/InHcOs+Pgy8lNGYadc3piMJClXDNWldnEo12PySRzejGT77Tg4kKeSiVFQLjGwuWesFXzJhLPxUlXSulN6o+LA4JJPDvBW+PY774+6T/lRpBpaQg9MQ0iI6ssSolIYnXW0XeBnDXWzESZbxXGVuTkGLxiHCBFCUKVFISIMwFnQtEsCpIxwXJyc01HdKEIKIWrDMkBlSVZUMahTY2iwqqGO6/d52h2jf/57/wI6cTx1OKt3HvxjIdvNLz2whoV5tx945iHDx6wnO/zf37sn3LztZt8z5/70/zg//hDvPud7+a9734Xm7sjx6933Ht5w60X1rz+yQe8/Il7XGneRu2v0MZL/PrHPsEv/sOP8WM//ONs7neQZpw+zLz8wjFpvMy9u5phveT2TU8c97h/J9BtHCcPI4v2+q78MGRqK2FiKctMo6lqqqq6QAwz+KDKP+T9rb7AUBSKV0kM516AKULUiZykZhVIT5rEmIcd6+xiPTbt2NPuPdW1UsPGEplRfmXZzeUGEL6HMbpYllEUKIISoERuprWhbWbUdU3f99y7dx/nLAeHS5bLBUptGbzEpChToRChstKiWZTbNIOZpOtisJ/TeQO6c61igsuEITglHehak21Gl9NNJ41xLYyGtFXUecHV+VN87tM/x5NPvJUf+Bv/kK//um/gf/rlH+fua2f8me/5CL/6K/8Xn/i1Mz79yc/x7X/yT/KhD36Yf/5rv8Gtl9dcvrLPpStLtuGEFz/7OU5ORvaXl+nu/wtee/2TvP/976HVLdePLlEnuP36y9BeI8Sez3zqFYYzx/PPf4p3PvduYszcvPUZZnsNi/0Z73rv06y2W2I9oPLk9ygntLUWVwhuFPRpukLS4geZBJfXn0eGyb/xkUqpG0qpf6yU+h2l1CeVUn++fP5IKfVzSqnPlv8Py+eVUupvKqVeUEp9Qin1gUd5IsFnNuuB7WYgeDHgiUEyZMYhkrNGK4dWtViSjZHNumOz7ghe0gj6bmQcAn034scoCpOQGXrPOIoFREyT8f2U2ZNKB19RN263e8jNIf7cdWOoG3GPTXlAmUDTVuwtDnF2xnbtuXfnjM2gSabFVnOUNWBkx8l4FFHIRAoq5aiUEW/EZIkx7ZxYnZNBzWJvJjCcAaUD2kTa2rCc1zQuiyg7a8IY0BmG/pTPvvjbvPTyi/zA3/qbrNYPeOPWy3zxe7+UX/onv0DKA9/ybR9isVjw1FM3uPH2iu/86H/InTt3+NjHfol3vfMtPPXMjH/w47/KP//nr3F8t+LWzcALv/k5jg6e4cf++49RuTlPPfUEV57IvPfLDviO7/oDPPWOyGufu4k1De9417s4W59yeLTAtp7n3nWNp5+7xO/5fV9OyCOHh0/QbSxj32O1pm0qUvSMQ8e8bZhs8M5pu0VNz0jUYot9fOa5c3d85AX+KDt4QELp/nREAAAgAElEQVSmfkMptQf8ulLq54D/APiFnPNfVUr9BeAvAN8PfCOS7PAO4ENIns+H/t9/xZTGVSZ6WUGSz6WC11otwa2V0+icdmiH+AtW/9IbI5DahK3LPy8/t9zTmcjkkZJyYBzBIVZiolOs0araeXZIcJQmxgI7BklvOC9zRk5Oe5bZYfYa6rklDAM+9BgtuzhKY5hkeQatDEYLJVXq7bxTrGgliQg5y/M1RtFE0Z26DCYHiJGYAymP/Kff/2f59Cc/xc//3E9z9bkDfv97vpi62uPaMw0xyiLPzUOeftv7OLy64Dd+85P8rR/8G1y5tOA/+d7v4OlnnuTk4QPe+xVfzjBume01fM03fymnx1usbRjdO/nDf+Qj+HTMV73j/Sgib5y+wo13PsH+1T2hL5h9lovr1LUlRUlGbpdXqNuBD33le3j9cy8y35+jVSdBUkk84NFKrOCUKkSuuPs7xpQIqkdToZJiterotv7RVjePZoB/C7hVPl4ppZ5HktO+BUl+APi7wC8hC/xbgB/Kcs7+qlLqQL058uRfeQmqUTDirIrSXfDhPCX27pox/SZo7eJk62ItPY3Cz+vvqdmc6KlSpqRYmk9lRYzrHE41hdQ0TRdV4VM4hhTweSTj0EZT1QaU4XTt6cdjhmHg2WevYl3GDolh7KFItORNlbddF98UMXnXuwV+sceY/PqMEa1iVmCJYoqTIzENRDXy2r3PMroVX/etf4Ar1/dxtiHmQMdLvOWZG3z1138x1lYM6ZR6z/F9f+U78GOkqWuMyfT5mCEf016v6B4+IDQW1+zx7PUj1quOL/+970TNBg73ZviwpbKwf3jIer2mXSZy7Al5ICggelL2VLWlthryiNYVUW8IMVG1xWclRIzSaKPxMWIuiCEmLa5MpwdM1qhs2Ww869W/3R38fBEq9SzwfuDXgGsXFu1t4Fr5+Cng9QvfNkUJvmmBqwsxgvOjRjSRSZxRUeL7oXZ+f8KcE84GDEEMYKqqwVrLdtszDMVeuWmKeGIsXxeje5Qw4byPhVgvY2SZjipi8qXWVWy2K7KS1LWmkYGQnA5lCGUUs3lF8IMYFDnDojE0i6Xwrv3Aiy+9SttUNE3NlUuX6TZr+sGjibRtoZXm835h4qQ8fPiQuq4JURQ6dV0XVUsiKo1PmcV+w2sPHrA4nJNixTYN6FZBiGzilqPFgiGeETIkAg+2G3osfpuozQylE4u5Iaie+dE17t094Yf+l/+do6MrHFx9EmM0i3niyuXIqy8/jwb6bcfLL/Uos+XLP/QcIYxsh8wYK8j30U7RVGBcxrjEzFlBWGwt7PgUuPakIxHpNpqsIRnhveR0Tie2ShZ/iLn8PWckX9NUM87O1hwfn3L16vVHXrOPvMCVUgvg7wPfk3M+u7hr5pyzmnzKHvHKF2IELz+zl6fRdcoyNvbeo82ErBRlTiw8k3QuUr5oJzCOo9gSQ/EVHHZSs5jCDpLTOu/SC+B8R5+M2pXOuNbt+OY5I6dKjCVstgylCKWUAFcpVJK31OrM6WnHSbcl5xV9F3ny+mWU6YXDokIRE5iCFsguLa9DpnaojLUVxtiy01uGOILVqEoTyGx7EVibADWT8EPyhLLS6JwZ+orMjNlsxjZ7fMz06zWmFhKXrmvuP1yTVcPpWeD+vYe8593v5PnP/hZ3ju5zdLgAEicPj1k/hFV3i/d9yXVOTk5oZktSSNR1hVYlGc1WWG2JZTjnhyJW0BbXyJrpVhFKGSaHtsaYTBiiBL0WaZ/YSChcnuNHuHf3hL3ljP2D5pHX2SMtcKWUQxb3D+ecf7R8+s5UeiilngDuls//f4oSlB1SzHx8sfG6OK5WKhcUpJjRhMmLAyh57DF6xjEUsrzaPU4MN6eyJRX+xLkWUX6PQIchhJ2/oLFTrS4xHDmFUkqwKyt0cZIViZXH+4g2hv39Q7pNR9d13L1zTF3XhWbrSFrCmAyTT2LRaipQyp6XXkXYEItky8eRoBSqkqxLCbay4tyqABQqGVKvcHVNJtLMKs5Wxzjn2A4dTV0z31do22HbzOnZXbbDKZeuHFDZFpuXdNv7vPWZq6S4wuotjbNcfuYJUIGTM08ctyjlUWmk0o6qalA54cNI9BUqGZlXqANC8CSdkfihkRi9mN9nGXgJY7G4CstOc6HnMcIvqvZ56eUXuHP7mK/40Bfhfrdk9l97PUrKmkJCp57POf/1C1/6B8B3AH+1/P8TFz7/3Uqpv4c0l6f/pvpbG43SmdmsJSTYdgPWVlJKaETtQwSVMEajs2IsLqgTdrxcLncWE5vNBoAnnniCnMWmzbqIc1XRWprdDZJL+SEQlWgG63pB1Yy4OuEqiEmUMgBB6Z0gVsopgRmTuNhgyYRxJKFY7LUcHC0xxnD73m3yqdygbVuzWC5Y7k0GoMLr9t6LDM0I+3AYxl2JlnPA506GI1jmdc0wZmZuhlERmwYarRiA2A3M64qsFTGsWSwy681dlE4cLp9ms91waf+QO3fuoMyCWWV5x9uusdizzBZC/jJq5GBvycGy4eThKZcWzxISKPMcJ91LXLuyz8npQF3N2K4HrBPhdkhx14SLxraSwUyOJB0JOTKrHDEnQpTyJDDZM8vQT5eGPGtFGAKvvPQC/bDl7c+9TZT/m+4RlrZcj7KD/17gTwK/pZT6zfK5v4Qs7P9NKfWdwKvAHy1f+yngm4AXgC3w0Ud5IlVlGWMkIeT/bR+JsThKFb6wKkY9E3EezieSU0NWFcs07z193+8mnVJeSOMqR34hbsVznoNYo6XCQ9mKxZqT2nsqiayp5GgtZZNMlMuQKReDUOsJoWfyUO16z/UnrjL6yHq9Zrv1+DgwT2uqqmKxWMpJoLXYXdSioZySEbSW8sMpieuzZBrrCEOPU5BiQOuI1YmgIimPaCObg9F7dKuHkAzzap/aXOLw2g3GfkuN4f4tT7+qcdWMo4M50crGceXyNfrNQ1abgNItrlqSx5F1t+bg0hHbvkM7TdSJkDQmJ6rGkFJHitKwZ4SekJIMOpQzVFpBlyQJmkw2SrB8o6R0FM4lcD6s67sVh4cHLPfmDN0G6wyPej0KivLLgPrXfPkj/4rHZ+A/fuRnUK6qqqDf7D5ebdZl8ZWds6jTp6DQCT2ZBj3TgKeqqkJK2rJaSbKZc+5Nj9M6/y5ViCx4ia42xpAJKG2L3lFODzBM+ZKTKMOgULaQtRAGnbNWqKU5EGKHdYZh6FDacvnyVR48WHH37n0av2I+nzObLXaiX6XCDhXa6RSVBQMWi89itGMURakuBvKYKEJdHcnZi1hCRxazJ9iOI5cOr3J6suWv/7W/zaxd8v73v5+n3/I0P/Gjv8iHv+r38/M/8/N84zd/kP/jl/8JX/Phr+HFT73GT//UP+Ubvu6L+H2/5yv5i3/xv6SuFbbJ/Lm/8IdZbTbMZ4co7Rg6CvoEfdfhw4hWDa6qUApiTuTosbDjDskysRdIVLn8rS/YWJRBXDurmM0bhqHDOnGbfdTr8ZhkqkRIKwgDKipyiuxVLTMjcCFomtkMQJq0EKjU5A9o8H3PpuzWUYnvnQOUMcS+J3QdNHNmezOUScQwkJM0oLHoACUaJJdIklOcNpJdmSxOtUQiGvDDCus01haTsxyJXpOjxul+ekEYpbHKAFWhHAzAQBg6ri0anty/xs2zGXe3PcevHHPp8JB5O2MMmbptMSoT4xqtthitqJ1hrGpiBFNn3H6GIXF8cp+6zrRXFxyvQc/22ay23KgrwviQk1cSV5+4we0XX+EtTz9Ld1LzzV/7J/g7f/vv8mf/zPvYs4Znnzhk+ZE/yMc/9jt84IPP8YEvu86v/Ngtxpfg7scVzVdcwqhLPHn4tZzeX7PHguge8tlP3OZTn4S33ahB9dy/d5P3f/DLeOrZpznenFLNHXcevMSloyOG08jT9bu588YDdPNA3KzUIBJFpci1Zui3oGqCqhm9ZugTpydwdGWG1lKuxeSLcOXRrsdigU91tKsieYSQxYk0RoUv4/u6aXa79DSG11rvYLTpZ0z190UiVs6ZLjuGwaO0J8cRpT1aVRwcLtDKFr24+JPUrqaqhiI6tmhjRSCsVFG+i7eetRbU+YliS0jqOe+ZMoYXg87pmoZUly8dorXmwb2H3Lz5OilEnrp2nTvdBmcVe7MWa8ROwpPI/Qg5USnLosn41hCUxllNCjU6G1Kq8cPAeg06z3jx5d/kl/7Zb/PRP/UncI3j4ekZYzrjL/2V72UYNphZ4PozSzp/jwer10nPX2b1dMv4YMFf/Sv/FX/xL38fX/K+dxN7zdidsVnd4cHNluXRE7TqjNXdl3nyaz7AT/3kz/KWa0/z6d/e8ON//+/zFV/1fk6HN/iqr32GbrhHvad5MLyMO7TkWKHJGAVBSQ5Q33l8lH5jb2/J3Xun3L9/D6Ms7Wyxe19FKvfoMWuPB9mq3JDGmLI72h1CIWzCuMOKp+klsIMHp+ay7/sLDaDe/TPG7JyZJndSKXESVWWpbHmsKAV334eSpIWpHJpuoosl0rmFw/kU9U1X0V5OLk3izCWYd7/dEsaRq5eOePLJ6xwcHHDz1udYr9dstj19SPQhMyYI2aKiwmIwWXKrKpvQSpy8krc41WBNA1i2m8g4KJ66cUhIK27ff50Hx7dxDQxhhWsyr978NENc88nP/gt+9pd+ku/+3u/i+Ph1PvPZ3+LoasPlJyve+d4r/OIv/yTRnPLse1q+6Vs/yL2Te/iUOV09YHGoSU6x9QPrbqSyexgatuuOZbtH9AM5eGxlCCTWw8jEHlK7ctOQs0ErR+Vazs7WbDYbKqdZ7rekPJIR6w5tEtp8gfHBMxRSkcZacXB1DrROYrFwQY8XQpCJpkooLeiL0hJ5gkrYCzFzFxebwaALzIjKODPV0xQfj1Rud9nJlZbvnTgp03Ooa7db9NPvmJ6b4VwYe7HG10Z6B3l8CanIUFkgBVLUNHWF3leEsWf0nqwym61QQ6vaUWvHArGYsCbjbMTojEq56EsryJFQGJR+jLTLhkvXHd/0736E5X7Dan3Gf/b938XtW6e89NrznG0f8Ef+6DdRV/Dhj/weVDPwbd/+YWb1PkfmEne2H+fbv/vrOd4+pFMGoxxf/N4neOPW6wQbedt7n+bwyRHbGL7m3/lqFmbJsj7k6hMzDi41RHNKGM8wesYwVqi0oB8DNm/JSibDu11MgdEV1jbcu/sa4zhyeHjI3nJON9xHabGd0ObzI1s9FgtcIQhCVQk2GnRG9SNWWbQxWKtZbwZp9opKZipB6rreDXsm38Lp2imDyoAno1GqwmgRD1utGPoRpY3kspuEs5m6DlSV3Y3PZcQfd8ls0++oG1fKJjHD8VlsiCed5bnH4oTcyM5f1wLkDr4XRqPfitxOW5688RSrlURsr/sB7TMuaIz3ZL0AEzB1om4SrsmkjacPUPUDs72Gps0M3ch6e4+qOaK6FNjfO+D09IwrTz3JZ55/gG7glVde4V3vfpYH3evcOLrOk7MjenXMpWua0I38zouf4Lm3PcV6WNER0POGG8/t8X+//NNcP3iWs1ihF5nDeea1129yeHmBzifYZsvRfsT7U1xdEYcDrKvZdAFSA0rThxVZJZRKZG3w0RCiIwbD7QfHGOO4dn2f+aIipYG6rnZ/y1jEyo96PRYLHFVyMpMQq+QInxw0zW73U0r8pYWbI4/zfmAYhp1ub5pkTo+fUJesIhSs1ZSwJKXEygEN1mSMFUN7W8Xd7q6L6He6piGUUooqVWhjBEFRCqU8KSkRIkwIiJ7Km8nRqjSoSoES3onPkqamciL6jvm8pR89nfckNCFDGBN9JZudRZF0JttEthlcQllVBik9sEUbS9NqVtszmkXL3v4Bt2/dZ915nv/UZ/ngB78c4zyHR1fp/RaVFGwN825BGluu1Jd46eOv0MeBpGbcePdVbr18l7ffeBebE4ffZmbzwGZzzHI+xxgxRhqGNavVmoP9y6y3A9ZKsEBtHV1/AiQZ06MFPswKHyFG8CFycnLGlStXODya0/VndP1alPllDiGUji+0EiVJ6aGNQeUs5vKVeO+FJIm3xsq4GtTO02OqlauqehNsOJUMF4NDlRqoGlvwVk2OYjlhrdik1U1GG4+tEou52jkyXay7p8Z2+h0Tzj71DJOtw4Tf5izYedu2csMqMbasjMVaYRLWTk6JcQzEFKncjO2wxWjHbDaj6wb8GDFOcdptyDqyXzfM9xbke2fgMjlmlBXBsskKpSNRQYieqqnZdD3GzZgvDnj19V/n2WefwTro+g3DqHBOnKWsqvnSt3yAxl3l6tGzbPq7rLcrPvn8q/yvP/IjfPlXP0nYq6lCy7BegxlR44amPSTlkc1agl9ts8fZNpCDuAsM3Za9RcWs6WhnltXa4PsR62akLNrYFOHmzVs7lqb3I0plFvOWrhN6BsjQbyofH+V6LBY4it2TloVb8od2bMGCczNhw28eb0/87kkCNT1ejjIZt2hTypuMeBgoCeBIqviq6EzlxALO2ICOdvdcZFwvP3Ni+snpMPm2lHDW1O9uvN3wR4lVmUxhRZZnbRnxaylvamdROTH4wDhsyTGBMSzaGQbDatPRbXrqNlEZSz94lodLrj5xDWU3PDwehTZbwm0mTD/JG0vCEUfFervF2YaqqpjNGmw1xzkPMRDGzHK54Euf+wAt11HMyfMrqEuJL7rxlfzjf/xP+bVf+DXI7+Da9WdQeWDsTpjXI10S4TDKkanJWlKQs8qsN2foFEhtIqRTum0GdRXrHDFAQJExdGVqO1u0+NCBkh5DLpkvTBzxz+d6PBY404JMaMApxYyavh+ISfJthjGQcv5dGOhEr5zQkYvoydToiTwqYbSXqBMN5HO2ojaw3GvYW86pmkwIK8jnWsmu63Y1/mw22xHxQ0hl2iqoTFOlnXOU0mbHo+mHLZLm1uBcg9KJED2MZfRuNNXcMUuO9aYT2C8NxEGM8g/nDd45bt+/SY9lVu9zZwOubThY7DEOazanHSY66lrR1EtQFWOwjCRaIykQL794lytXrnFwuMd6dULwp+zVc/ZmB6hUE84U/93f/gFWp4l+bfjKD32Ar/2DH2HZXOGv/Rf/DV/9h97PJn2Sb/7jN9i7PGfTHROUwuaMzppI0dTmgCJgNIzbyOH8iH13hdt3DEMKqCsB4xqGHkI0nJx2vHHrLkdHRyyXC4b+DOumrJ8AtMV5Ie9O1ke9HpsFDhPqUcqCyoivSdRFkxnK8R93tmjTglbq3ND9onvq9EZIc5KplKi7rRUCFbm4VxnFbG6Zz2qsy6zCSsqJHZ01ML2nphHq7oTo7Eql4o47lTWyuEvNbC3igSLZkt5L5mM7+XwU6zalFE0tXovD4FkPA0ZnKlPTzCoejNCvB6o20W8jft7jTWJ9ckqOLUFpmmJqGTGMKTH6ROU0wygfX7o0Q8KkLNlV6JTIPhK6nkWzzx/74x+ldgcsquucnNzDB8Nm8MRQ0VZP8OqrN+lSg0kK215m22sOrCjgFYmcRlQcyT5T2ZYcWt5+4/28961fxo9+7h/w/O/8Fot3rLh8+SrGHdFtPMcnaw4PD1kuFxibxXvGaMZ+LGXk+a49/W0f9XpsFvjFJ62U7GqqaRi9EOPf9Bg16a4FXpJxtgxfvPeQpNbVGYxQ/QRKS7nYqoFzMkCpKoNVUDeixzQGia7Tk/Xa5AEub/IwDKIfLZpBVZQ558kLJWBWTa9lWuDyvGXnj4Q4srdYEGPGezF6h+I0aDTZGlonPBxUJMXIc5ef5Z5f8fD2wOAMB0/u4+ZwZXnEnfsbkiqm8tYQk1iljSGy7aQ+zlmJ118aMCrSzGoMEb/tCYPlS77sfWgWWLvH6BNOz5k3M4Z1x9nZiuX8OvcenMoNOPbMZjWwIKsk4hEVMSlK354MD94444ue+mre8fQHWXCNT33qNT7xyRe40YzM50uqFFmve8Yx8ta3PUXKPcMo0eJTmp3TFmV2GzgpZxRfgAt8osuihXthjKJpWnTvJZ6DSeWuSTHumrtJeDyVKFPJMu2sE6RoVUMIHePoMQ72D2uq2rBoG1msKeK9GN809RKs2U3MmqZEiqfM0A+IAabwVPwYdyjO5Us1k1/ijtOSwRTURAw7ux2Ovj5blddhCjEJqrqi2/aopDBZeDDJSwz4c4sv4j/66LeR2SNT8+LqU/zwT/4Q/TiiYyZnD9lgDAwq0nVrusHx8OFd7tw6QVEjqXI9VYgoBxaNNZbGzXjXwTux4zVmesG//21/jH/v676OP/XRb6epFe3lBfnkFH98hvL3WByKm+z8oGZ1uiaVPqbRFVovMCz48O/9Gt577RvYpI6/95M/wk/89E9x9UnD0ZXnWB4c8Zsff4nF/BJvffYdbLdb2j0DfiQlT0iBxeKISs9Y9WfnC/zzC1l7PBZ4CLDuLK6yxOBJqWdhLDqPbDYbsesdRlR2WF3Re4kpUQaS6sWIXTmMqUQUrDJ1XZNzzdAbjK5xe9uCd9c4qyQwVVnRBubEGEbGmAAN2rJIEZtBK0efDGNWxKTwWoPOKBXwQ0B8rw3W1aAtxgkPuxsGrFXimzJGqqpmGHtSgtlsTsqZrfJoNE0uNm85M243OK3JKtMetqA0227g+OyMaBQdI82oMdTYfsGt28eEq5oHsxGbICQDG4/PkXZvxl7c5zie4qPn+nLGveOXufLsZU62Z9hcUZmGh8OW1faEgYdY/W66lPjBH/of5L2xhi7XjCS6PIov+FrBYeK0vw1uZD7cgCYQ3MBZCsRO8aU3vpL3XPswbXoChsAP/rf/iCEdoOdP0ce3cvPenLxw7N+oqRcnLH1Ge00dHF1qSK6mT5kHYU2jvBCvUmYM6fNa5I/FAleKUiNbjLmobgnEeO5torUuxpxewlCdZFZOqAW5EHdyQmmPyq6cBtPQJ5VpqcFa2WHHMZSRfUXMsvv2oxdVPGVSucuI0bvx8vR8pnpcvA+rYtKfyFkwcx8GmqYquZqOnKMYHCVhI8YYhQJbuCoXS7XJlg0mf23D6HtMGJi5PXJKrE/WxEqha0W37rAN3HjqCn3wnKxWPIyZai58nb7vubK/4Pj2Aw72a2amxilFVWsWuuY3Xv5nfPHRU7RtizGK3/n0Z3n6qbdy5egJhhzJes69+x6yY9iOhBSptWGTTmmMESsIFPOFop53vLL9TZ6dVfzXP/A3efXOx9l7UmP6nngcGGLHfr3EDpqo4axbU+sSf64zPifJSuIc9j3vq77A2ISqEJbOzlY0jaNpG4Zh5OzsYUkjrtjf3yMnS4qaa0spL+pGobTDj5kQcrEzboQPrTUkJar8OBKdYRw35GyL4kfyaaxzRVwwyElQjCbHsQc0MZebpwxccnlzjTFFO5wgiqzt7HQouk6Nq1QRQ5QkMhN3kGM/9KUxrok+EHPCWYd1mjB4iQnJAT/8P+y9ebRm11ne+dvjGb7hzjWpSiXJkrFsWZZnIWwc02ZoDPGAwQacACEBEpqFV5NFA6uzHAcCSWiHbhowBuw2UwIEY2NswBgs23i2kCxr8CDJ1lRSjffW/aYz7aH/2Oe7t0SAlBbQlHv5rFVLqlV1b53vu/vb593v+zzPr92bwOaFYqgsOIdRkdA1zE+fZfeB09hqwA3PvhGfObZWx5w8/QVyk2HayI6bsegapJc89eqnIKuO9YObEB2qqhmtGkysaEzHAw/fy4N/8TZOnDjBn3/4g2hjyQclzgsWrUOvCL7i+c/mmgPPZuvAmMwmR/8Hzr6XMAscXr2MQ6vrzKo5j3z+0zyk7+H/+vhPkmWr/NTP/ACv/Mp/SqZG7LhHkQrO7J7gjs/czqfvvRO7aWhlQ7aaoUVHPZng2xaDpMHuObmWpcrFXpfEAkeAySy702189Jgsp248kaTk8z5la0cREBqGY0OWpUldRNA0XY/rCP34vM828ZqmjrSNo3WJEuB8i/cG7wVE1ysF+10iUaGIIdC41K0RMhKlILg0ZXUXdDyEEGgh+/weSexin28eqesGrcFYiTEX9HHpc7FV71SSgSgFiATAldr0iVZpUuvjPmpPIhLpmEjb1gyynC+/4blsHjvAK1/xz7EYMuB0fT/3PnAPH7nl49xz7/2I0YDD4wO88MYXct3mkzlbnU/qTRdZyUs+eOLj3HL3X3Ddk6/n6Te+nKqa86pv/zaG45yd+Tne/o638ck7PsXzbvwqnvTEp/DC678KiabDIRFovcH05A5H1w5y7RVXEoSnoeUDd32Aa47DS7/uFYz8BnZ3CCFnbXOTrp5y1crVXHHjlTzjy57Dq37o2zj+1CtYP7rGgStW0HmJVorQNtRuH234xbnAif1wQuG6SLVoaZqAMSVESdvUtG2N1glMNCg0xgqsTafq6AMii3glKAqZuDgEvCOh61xH6OjLHdMrECEqT6xTH1triw+pVKqrBusCQiWgkosR1/e+lzyhhMlLu3la7MkMrIzGh46qatABvFDkg5woXbLmkcgNyhjw6TXTO4ZC6HPOl4YAufScxmRgCBEhJS448nzIVcev4Dtf9U84fPgY0zrJF7wKHMw3WXnikOuf8FQGH9rgN37/bTzx+ivZLDcZscrcwXpxAKM1LZ4P3XwPf/yBD/H8172AFTPARsH6uMDRsGILHrrvPp527Zfxkq//Go6WlzNbLCjUmPq8Q0TFsw99JRN5nqEZYhcZ5JCrwKm73s0NT7qRw/oKRnod4hZMWurplHy0Aghk13B87UlcNn4Kf/GBO9i6cosbsmtYXbWUhcUrBdM0XLtwkV/sdcnIZZ1rGQxGaJUznTR0raStBcEvOxEJ3ad0UtMJPMHXuG6OwGONoCwU1kaMjkjpUNKl4Y5we/3ppX/yQmrAkiKw/wuQyWzRdZ62WSINE09yX5fe7XVuiCmcc7k4U2hPpOsci8WCtnH94ShxOGNMT4X90b6naV3SnfTgpzQwSqlJIH0AACAASURBVGpJsewwaUHrGubVjLZtOXboKJacQRyxWh6g1CvYmGFbzYZe55tf8AoODrdQjWAgcnznODg6jGgtodLc8ZnPc/Of3sLtt92LlUN8/SgD01CgUEGhGXL3Jx7gn3/LD3C4PI7CsFmOmZ99hPe/5w/48M1/SOGGHFw9yiBbJ9QaP5O4WnLiM+d47hNuInMG39TU2/fh4yny4QAQdPMa9AAY8vm7z7I4aznzQMfnP32OU6cWNE4hs2yvRQv76s2LvS6JBR4JdLFFaou2A0LMOXFixtlzDTvnWxA5Jpfo3JMNk/57NpsxmUx6WkFLCEmv4r3rf+9625lHSEeWWWyWgi071+wZF5b967puads00CnLIdLmCJODsniRavFlCH9cpmP1ZURc5prIGi8qPA1CgTIJY3j67DnO7y7Y3l6ws9PQNIpqkf7d4KF1gapxzBYts7rFIXEYuhASwq9voe7OF0RpEUNLLTzFaIzrBPd99vPkxTpv+Lk3ctsn7+ITH7mVPNuAGjYXm/zCj/488lxg96HT+MUuzews0e+iTMPv/sFbEHbCldessLUVueeejxDdOdy8Rs8s7lHJD337azkkrqRoVokLxTve8buMNnJe8eqXcviaNT559wf5kw++jdsf+ghn9VnqosER8a1gJVuhns7xesHD+i6++6dextOf94/4F//rD7JTdsxFw5v/+NeZBc9weIhcbPHg3ducenDObOJZ9Kympanl8RoeLpESBYRMtq9I0nobW1DVHUJJLCp1GWTEx47gTU9V2Gs9EEnhncYqEH+JT+kT6nrZR192JJadlcdouz1E4YguEIUCqVI54SJdiLjYYWIaKikh+lD7ZffDQZ9gZcw+Jns4GO0F7jsRUdJCFLS+AVKQECKZnn2IKK1AeKzJE0Cqz1Rc39giIpnXDYdXL+cLD97DH/3BOxmUq3zs9s9zx72f5orrruB//kfP48wjD7O1dQA9M6xvrPHcG55DaQqk8thS8J73/glbW4epul1OnnuAfCy5/daP8LJnvJrgk79pPt9lMBjxvJueglS7BAKmUDhl+YP3fJhP3fFp3vmH7+Z1P/kazk7OcrqZce21z6BxLV3bUQyGoHNUlqOU4eSpcyhTcuLhe3j45LswhwzHn3Scmz/4Phb5hNwEWjrWRhmjMiP4Dtc05HnZ4148w+Fw/+d+EdelscBFyurzPZ4boCxL5vM5Sz76YGRQRoDoqNukzNNKIKRCGYFAJ56PlsnHKR1EQVzCS0MPsPpL7ppwAa1tOTaPXhBiAkApqZEiRRZL53Au7meQiH3prowpt0WQ4hOWO056eeoxxoi6bum6CCb5Qk1m+25JINkmNFImHbyIIVHWItS1o8Mzytc5s9jm1JnTrK2v8/JXfCuHn3Ad589VvPMj7+LW97+btQObRBeRXpMJw5c/93lkvQ9VSkFW5Pzxn/wRw/EIIQ2DcsDXP+sbmFYZ9aJimCuEDQSmbF2W0YVzVE3LanaID97ySX71N9/G9rmKq6+9jhuedyMbcoNHzz3CuXPbyCAZD4dU1ZyqnjAoV5ksznH1kafwpp/+TW77zlO84U0/zzve/XuYTygOHD/IE555mDOPnqOZz1hZO8TW+oDSQOg6gtmXH6dEhS8yw0MMktmuYjLZZemMX98csbaR4UODcy1N02D6Fp6PEmNyVJJtoJVhiRPsQn8QRKK1weSKzEWMVxAV2ixDNH0Pb00yXKU8IUpcDDRtSxDQOyH7u+zLkhBwUaFCQPZ9WdWHD7UuKR2VihATuUIIwaKZJ+9ov5C7rqNxDaVJ7CDfxpTipBTGFHQBQheZdQ6JJ307RVs34CVGWc4vKp785Ov48mfeyM0f+3OOPfc4RwaKebvLuz7+Hl787BexZlZQVvLImZOsb20h2opm3uCV5IVf8fXc+Jyv5n953Y9x/oxgmI/4/ENz8tFD5EVBFR3ZoKBatNhiiPOG1fEKJ6dneeOvv4V8vMJ4NOJM9wh/8odv5alXPZmjq0c4vH4AJLTtLivrgoe27+GaI9dgtWBcHILTFddfcxU//brX8vrRa7mvuZefffP/yfoVG+SDnPlkl51zj2AHFQoJrWdaT/szT2TRto9rB78kavAQYDb3VE2HjxFUyhZBd+QDw3C1oGo7JrOKpoMsz7FZgdKa1nU0bUvdNsyrBT4sYdmRQEBqgcnM3o66f7DcP2gCj9nV0yBH4vvU16U4yjm3z/GMYa82hh6whEFJg0AlLlB/iEx68NATkVus1ZRlfkH0nMCFHsIakmuldQkI1XWRrov4FkozIFcZk/kuRzePsFKsMKsn3PXpO9m6/ACHn3iEp7/gGbzvI+/jtjs+2XdgOsgkU1fRxcSgNz2u75aPf4wTDz/Ik665GhGS4fno6iG0gTyzTCYTrM2QqmBQbnH7HXfz2//199BKMBxoBDOUmPKim57H0699MitljptPcdUMOxzTCcEPv+61fGHyCMYOaLsKBhlKVWjRsqgnXJ1dyev+5et491vfzRfuuo+2aTh87AgrG6tkgwHWlOS94dw510t9y4teW5fMAq8WAYEhyzLyXBNiQ4gLIg1S9mE8GLpWpMVFxAVP07a0rqPzrvcyhhTHKxPfMZCY9EslXwrU2RdQ7S/wdJAxJkPrlAp1oew2IOh82Ns9lrX98vskw0OGtSVa531YaECQJLZJA96rDGXKNVx+3VJTHnrYbdt5vGdvOht8ospV0wW+7lgZrLCoF+xOdhjmI179Ha+migumfsKCBXaUcc21T0QqS8wFelQSpACteoJE5HP33MGpkw/QNjssFmd55jOvZWfnIaoQqScBGTVKRMrcsLv9KPPJSa5+wmW84qUvxsbI9smzUDm2xhtcuX4VmRhjZIEuh+jBKpECWa7x+++6le97zY+xQ8CurDJxFSdP38NgaBmGjIKMFdbR04yPv/9W7rz100zmM7yQKG1B53sb0YWq0Yu9LpEFHunaZRB9hs00IbQIGWi7iqpeUJYlg8GI4FMkWF2nRNmly37PaECymcGyn7wcnT/WvHzh309fs+/AX/r/pJSo/g1dHliXAx64MNcw/V2tDEZblNT9B2df7JVl2d5rS6lbC5KFbZ/FvuwSLD8cS1HXMid9fWWVnXPn0aSdPzOWNjQ8fOIhsqHlsiuOcvLso0wXU5xvmS8miCJHC4OQGquypCb0Hfd87tOMRzmf/synuOOuzyLUgqY7Tz21HNp4AiIorFZU9XnuvPtjDMYarVsuO7DJi174VVxz7Gqec8NNfP93v4auC7RVg9Elu/MW9IhJFIh8ncHWGu+5+aM87cufx5l2jllZ4dDhLbp2h4EtaSYtY1a47qqn0e46HnrgBHfedTcPnXiEnemCpg17ZzFjzN6Z7GKvS6IGDz6gRGB9XVGUAW0Sl0f3A5uUV+II0iBjRhd3qeYJ9be6utlLWBMmsGoENIIQMqzVhBjpQstAZRiTUeQZZZnRhQ7fRGxuiSG1+lJZEnASSruC78fDnXBIJdBRs6hi2u2lRvQqxMaDVh0GT9s1xOh7nUpHXffdnL3g0J47FBXbVZLr5nqZvQiDcYH3nkU1Zzabpd3fGjoReGA+5+rLDjGjoaDENRErNdcdvZYf+pbv5b1/8TF2p9t83z/7QY6sHmVWn2UwqwldyX/7rbexXuZ8+3e8hN1Y8ZyveRFbZpNfqT3mUMnmsQ0Gdsya9YjFeaQVDNYO8q5b3sv3/Ot/zcMf/zSZHVIt5rzljW+irmcoH/F1izFjoq+YzCeYImdanURpTX3mBJ/52AcY2yE/+caf4Jt/4MVcfuVREC1Pe8LTuGFwPTfd8OWQWV7wrBv5+K23ods1Hv6kYvbgnEOXeS67vODA4RHAXnswyXQv7rokFrgQkeHIkmUp/XVpMl7674SIKNmr9aRESJugrU2D98uI5TSg8X2oZlpQpu/MBFzs9o6Ly5yVSCT2YfR7xoYAWia5rorQhYj20MXlNDHx6IXQSBlI0/0UUiS97l9PmmwuyyEpm7SjiyXhLbUZvQt4+dingFIKqQTW2yTW6vaHSbPZOSwRSUr2cp2n8x2xCzzpsis4fvQK2hcHDpUlIlQcyMfQaYSTvOEXfpGrDh/gm1711ZRZxufuu5eff8t/4t/+xGvZrk5z9313c/BJx1nsOlZWVll4h9fwgZs/Sm6G/MwbfpHvftWr2Vrbog0tK/lqep/lAoDpYk4xKHEh0lUd0irqRcem3WLOlH/1nd/L0558FafPnGRn8gjGRW666SaK8QGq3XM8dOoUTUxSCC8ls9mEU6d2GKyscfDYUZaJsyEkJ/7FXpfEApcy6UuUdkSWzEsDpLhRIXoNQlhOtASDckTXdexs7zIcDjEm23u8Q18+BAg+poV0AcrEObDqwliJJfgpfa3Wqf4MRPCRVkZ0DL0vs8d5S4HRiVsfY7rBJbs+cSENXgiWKO/0SVi2DWX/76Tae3nF6HE+ufaNUXuwK+9SKTMeZnR+jnCB+SRgkNj1Nfx8h+NrhxFkOAImtoiuxXcNajDiDW9+Aw+fPUUMNXlWEpFsbKzzTa94GWhJYSzT7QnttGZl62qq7XMUmxt84PaP8bGP38KBQ4f51d/9LVRm+Yav+1ouP3QEgwJichTNtnn/hz7As5/+DNZWN9DaIrXlGdc/E41mhRHGBL7l+d/IIkw535zls3fch7EWhIPcsFNPaVXAiEhRJupE21bMpvM+IzLNSDrX0LRfZIMeZQSDUYouXvorrSn3XOtSSHzvz/MBZM+tybKSGCPnz0+BQJ7n5HmShoYYaNve/BoVAY8LHU0XEW0gH2RkRQ7BI5BoKdE2pbhqbYmxQoQUBqS1Ty4SEZHK9CGggjzLkkKwr+sXs15TIxVKZ6h+x15iSFLtvi+kiKEj9JY8ZZYBlBHwe/HOmc3xKrnua7fLUKUzgd1aBwST3W3GK2t0vqFezBiVI7zXCKswdsiPvOWN/Ny7fofVG6/lzPZp/qfveSWv/JZX8MoXvSJNRHFUueXGr/pqmllF4R+i2BzwPT/xL3j7O9/FlU+8mrzMeVS1/Notb+e9D36Uu973UXJbIFCcOb/Nzv0Nz3r21bz5F3+J9Vwho2A+n3Dg4AYKhWsbbKPo5lNGq0OyYsyx51wHZDhgW1fscJ6n3/RU5k1gd6dOhuzgqaaCyWy6Bwfzade66LX1t6Gs/VshxAkhxCf7X19/wdf8qEiUtc8KIb72f/hvQOJQ9o/oJcFhX7XX73IikKJ1E1IweLAmx5qcGBNaG0RPRUim1Rj6dFapH5NXeKFReYkLkTIZKaIP4FNcMyH2/Pl0uMz7jHFY6lfSfaRSRPVDnXQv3iXceDrs7u/eWps+q3zJg9z3kC61LPtdmhTur5XFKc85tpmEKU2s+PQDn+Nnf/VX+Olf+TkaJRmOtoiq4JH5jF99x+/zvFe9hP/7N38NvVYyOLTCyuWHEIOc3/q93+Wl3/1NfPC2j3Hv7gk8loilEnD7g5/i3/3ia7n5Ezdz+ROPYDLY2T5NuVKgS8Wp7dN813d9F2/9nbfywz/8I1x25HKue8blfNu3fRvHjx1HaUlhNKPVAb/51l/nTz78pwSraUUkP3QEX3dJpkBBg+YLu4/ws296A/NmQT7MGAyyfnoLMhqkKFACjJJkRmN1Ovxe7PW3oawB/EyM8f94zGIV4snAq4CnAEeAPxVCPDEuG8Z/5RV7PnyBIMlag7hAJiplH37pkSoQfcpCiTHSNB2DwQCtNdPpFLHnj1Q4t086FkIijUVqDTLtkF3XJW6lCKmVKNNwxkWHDKnsSBHFyd8pIakO+3Kn86CCJ/rUw77Qxe9c22soBK4LKB2BZE9LaI6IMstAI0eM6azgQ70HgyUKOpe4m1JqZrHhv/3h23n0vnPMTklUOeKDH/8oOs+468EHWR+sk+mc933iQ8xDzendswxXNxhujNmd7mCiZzQ8wGC8wm2fuIXX/NBrePk3fTMbGxssJnM++aFPwPAs2XjM1tEjNLMGX3U89eprueOR+5mfnXDlkcv53ld+F5v5Fus3rnHTDV/B9qmHeMZTnkavdicSObHzCKemJ/hXP/oDvOB5X8U3v+zlvOBZ11OsrpExZIbjF37tjXzolj/no3d8hGc+/3qkdwgspo+xFjK9V4PckOd9REdMROqLvf42lLW/7noJ8Fsxxgb4ghDiXuA5wEf+ui+QKiVSeSdIu7Yhxq5Hj3iqqkFpQTkwhOioZ3rPSaNU6h0LIRgOh0wmE3Z2PEVRMByWfVtQYO2Azsl0+HR+7+ulTjW31RJJR/BdMtF0ieomhaCJEYnASo0IGoHCqtQ2bOsWRD9hdandqI3CmBKle1S3VrRtTXABH1rEMtIipnpbEdFCJbNxzGibjv3cFYD0ZJuJwAOPPMj9Jx/h/EkB2qKPDJBacev9d6K9QXjN1DtCoVHZJpsyh2rKobWCQZnzmz/+80Q/R/ca9Jd8x7fyU//uP/DU49cifzDwb37jJ3n7O/+IV7381fyTf/xKjuUHUMAZzvPLb/llbnrWczgshzBdcJkac9nKBmxu0jYNtW/Iy8gDzQO8/v/5zwyuzBn6Dd5//2386X+6FWs68kyjW0HdOhYuwQ4OXnE1u2cdSgaUDAwyTetrlOkYj3Iy6RBuAUFi2CdWX8z1uPrgQogr2KesQUKVfEoI8WbRg2D56ylrf/337XUdiXKchjFKp7ySSOogLMsLpZYHt5QT+JdR3lmWoZTCuXYv5ktKiQspIiwESSS55vdijkPE6gSDzTONkim1VYqU851pk0LtlUoH2c71PfF+6OPTAXPJ+blwQppyCnV/X6lMWZYhnWv68iiZKbwD1yWPaowKY7K91ywlBBUQmYBS4TMP1iGNQ+oGW4DMIGpPEB5BQMWAFB1bqzkHN0rWxyUWyVgNKEXBop7ytV/7tVx17DgWjcHwyld+O7nKePHzv4Yj+RYKmFcTCC2dn3HHZ/+ChZ4iRkAZOLd7gtq1xMxQlivcM32IP7/1o8xjTbQRkxtsbjGZRmUaVSjCoEWMPWasELnEBc90t8I3ELqAkA6be0YrgvFaxKikyQmuw2pFmf89tAnFf09ZewPw46TnxY8Drwf+2eP4fvsYwc0MiH1EQ6KgaS0TEKofgniXtNmI/W5H8lcuTQIKRCAEwXCYDp/z+Wxv0FK3yVWTcglN8mRKhVIBKRIZQSuJ0BIRFd6FlNggJZnSKcU1SoQLF+wgyY2jRPrwuaVxwXt8G1BeIRUpINRIlEyDiiACHo++YCC1lDiH0Lc9o1q+T/1rBZ0rilHOYCVjuuswEoyRKCnJVkvmM8ds0iEnDq0FMkrsyHDk8nV0pplMKzo6TIi09ZzVcoXx5jq5HOz9XEJdszEYcOXWQaBFoBkVBTvxLNmq4vb7b+P9nz3OVZddybHxcbJNTRNBodmh5pd++79wcvtBilGJ9x4rFR0BKSPjlZLxSoHLUhzd+fMdwQlUp8l9Qs94wGaefKBZXResb+ZoI+m6lJxrpUabv2OxlfgrKGsxxlMX/PkvA+/sf3tRlLV4AUZw46phXDIwl+GY2siUDoXEO5lafS55ItPIO+7JXoUQqV/uE08yBXBG2jYRiNu2xYWVhLqLKdothJauC+R5BtGliadIk0uZS1xHylOhd9YERecFNkuuH/pQoGVqrM0MoW1JR+Z+2inSQbnrGqxNMKZlkKeUksxqYhA0TR8oGRM6T8qUO55YN/3r1BKjAqvjnO7oBsN8FSMVmvTUyMs15nPPzvkWfWqXrD+jjA6M2DgyTtmBvu7lYwptMxocO/Mp9555gCduXU7Xzfnzm/+MoTYY7zE6SYB3ul3e+BtvwNkOMRL8zs1v59B4i+uuvJYjG4cZZMf53P0P8OHbbuHWL9zJeN1yYJiEWiooLAJJJNeCIpfkB1doXUDnNV0dkZ2g6BJ2RmeCfCwZrhrWNy2r6xlSGWLn8SGZQaT/O6zBRdpC/jvKmngsvfhlwJ39/78D+C9CiP9MOmReA3z8b/43SEQz0z96RKBzC7SyBB9TyyxkSdLqO7TuUukSHT50vaYkOWryPGkXEIFDhw9QVRXT6ZRHHnWEUKehirSMxpYsS4tUK0Fm05BJxAZjFIPVHOc8nQu0MTnfUamH08kUPhNCICwTq4Tod5b98bzso+GSGrLqF2vqb6cRPaQOik0fKDSZLfvuTIeMAWM0SqcP5PlH70fbkiOHxlx52RArBdE11M2c002NObqGqmB2X8dA5VgkfiBx2ZTWObqsTfffeRbzCfn6Bp/81O0859pncaKBotRkRcE3fv03MhY5s505LlP4zPKyf/wt/NJbfoFP3f0pXvwNL+VFz/hKrj/yRFbUgN9915/xoY/ewoc/dTvdOixczbntEwgH1q9itEHomjBqYSWwMV5FaMXhg4GurXFVh6g7lF0FK4lDx3AoWR9achloXKSLAodk0Tq6x5FP+LehrH2rEOIGUr1wP/C9ADHGu4QQvwPcTerAfP/f3EFJl1LJDpYiGBxdl3bfzIyxNmNapc6F0n3S0wWB+EtJSbKIdcn0wDINNpkPxuNVptO2pyAHqoVAxMhwqNFqiSMJEBK73uoiff+kemIZfRxicv2IPhb5wjRZrfcBpV3X7JUyZZn3mShLEFba+Z3veu141qO5TcJtNxUx0H8IVMoydIGysGhjCf0TSEiNtqQWaHR02lFLR0vHwGRoq6l9RZ6X0IU0REOQW0ueHeJ0OIfWmquvvIpj2QZtmBFksgh2XcA5GKytsNNOKGTJPXfcw2qxwg+87PsZUWDqDhaCV3zjy/jqr3sJr3/Tm/iv73s7OtNUbcUgLwguJYs5JSjXR4wOjclMidCSICqUNKAhG1ukVjgDzoqeKaqJvkkWvl7bH5F7jNOLuf42lLU//Bu+5t8D//6i7wKJCBmCPqLBKYQrqBc1wUiMiRjTM+iFom1sGukbhzYJuS0wCKHpugaDQghP2wZiMHSNxfqKzeGA4Bpi5QjzkoAlmoIYwOUepRpQNcK24DOUDGhlEE7iokD5PlmLQOtbqnZOoSDLDDpTTCfL/mxAK7snM2jrGqtk/253aJmlyGKfDpFN0xH7OLkQarx0KKOwxoKT+AgilCz69qEIHkVL13UpnEdIRNcyEAsKpWmsJ88FXVsztrCLRynDxmgFQ8Q7DR1sZAcoXEcjJpzBkLHC6d2KdT1i0URKW+IXC4yGyhsye5Qf+Zf/GyN3mM7VPLx9nnM7p3nmynUUxvBj3/ca/uCPfx+hUttVKU1td1FKMBgajo02GcYMqWtSQvgCoTswPXAwy8iEYLWwe0ACJ8DVc5Bgc5Gi9eQXWT64FImI4F0KxJEKVBDYLB3KqrqjLPPUDXEOYyxKB4zVGLvUoID3+yNcYzKsMVQLR9N0eC+JvqUsLaPxKl074/S5czx8omZ1bcyXFYfIy4zE5BRUsSEQUudCGQwSGSLdvAUpsFqTFRu9yhCiT4S2uMSk0B+IBQwGJT40e+rG5dkh+oQmRMbeHJE+ELmVST6Lx7lmrxOkey0GIYFThUzsIalgNByC0CwWnrpuEapFKwskyQL0ikmSJEDL9KO3UWGiIEOQRVgZSX77V3+Zl1z/bFYvv4IQOjrZ8NP/8d/wXf/0m3nu9U8mugkh1GxsGI4deQJzd4ZcrzH1Ozzjxi/jC498HjPMqVzNcJAxHJasrpaM10CqBT7aNHuQIISmVy6Q5zlSJBth2zhC7AixZZAl/fde8M8XW2zEMopBSsOSH++9J88tTdPQNB1VVWFMbwWTidUCbm9KGALEoECwV7ZYkxFjEjUFEfDB9TrjyGi8xoobcvr0SVrXcOrMDusbI8ajDIKg7pp9WFJ/WAwxgAqIkAi9SmV9xyMSImi1XzrFGHqeY0BwAfiUFBS6RFdHQh/jTA+V3ceX4z3RdWk8jUILgyemAMpl2q1I3lAlTZ/qtf8h19riaPtzR09/g72wTERERYGJCoVAE1lbGaCFYDAsQSpEbLFSUi2mjEcFikjbNRgrWNQtbQbbu2fY2LBEJTh8ZJNGTLn/0c8zWB1w+NgWRZEhlSeKBVKnjpeAZDnc+2AruqZLXS3Zt4JjUnFKejRNjAT/+Prgl8YCjxHn2t6o24uOXNuHxacgnaat8CFg+rbcsg73wffJU+qC75U04FIUvRZFULcVmU0LrvU1a3mJUoaiPMZsNmN3d7dfmGNW1wbUYYYWaddLSBJPFBFpIqHrIaWuRclUP8s+70SKpdFhHzzbddXevS3/mxa3J4o+r7zPhlnKFHxMdraIR4m0kGVPVUZ5hGNvN45xab5OxDKlFIq0GTjXIuJ+1FwgEkQAFUEKVM/0VH2nQ6I4ePAQNssBwdmd88iRYX1ti3vvvZ+bntYyLkacn2zz7j/7U+64+3auecpxposWZYc8+OD9nJucYnNrjagDZZlRlAYECUIgPEJalgCApN0BIsznqSbXvXxYSoVQ+3ODC91YF3tdEgucmGJDRUgTw/SmR3zfXsttluLKokfEgFa9vDWknG8h0l65HBYJIinFJ/QkQEXTLMiLHKESNXlWTbC9ms/mhhAGtF3g7JkJi0XNYFQQdBJhSRGJIg0bBAEVlmVR2h2VNAm/EjqIsU+fWvaw09NIKfWYXHOAfiB/gZwgZWyLPrtFEDH6AldR6kAiSQuV4Ik+YYZE7BNthcTavH9bBSImpaRE9k6QiFMeE1MIXVACZCLbISPWFGiV03gAzdrmIRpazpw5x+2fvJOzL9xlvL6Ci7C2cYCrr7mWl730G8kY49C8/3//HqbzBQtfsXZgldlkAqFkOLIYa4mhToM0mXbwvQYBSQPkg0vvYR8EJVEXkJGXoT9fZNmEy0BM5+skjlKK8cqgX7Ae7xsGw1S3OeeIvkMIhzUGUMQg93ZqqQRZ3udoRJ3wglEwHm4R/BznAjGXIDp8aNEmQ2nF2uqBvSjm3Z1tvvDQLyZXEQAAE7hJREFUObIsoyxyisJgVBqXF5lG2kRjq6t5aj2KDi0VIiSdhBD7DiEhFFEnzk8MyVfYVGlHHxeBuIc6AdnX4EoBIaCNZljuo8jnbSDIQNDgfB/Q33W4GJEmRwowVpEZS92kwCGtZQJMAUIFalqiEKlUQ1NZQWUiFkcralrdcLY6hVm1VMxTHAeBYiPnts9+gld858t5yy++mYMHD/CVX/l8Whoiht97/x/zW7/zeyxiRWbHmFwx2ZnTtoHFtGY+tRy8LMNmBVK6NDvQskdApjJyY22Vrg00TZdy0qMgdAkludwElnOPi70uiQUugMxqujbQeY/3LUJBXhR4KXAy4LoapQXWKBqXAE++rzcFBolOrTupkXh810Ho6BqPiJK6ackKRWYMRkH0Hp1rFosZg7JEawg+mYKHoww9GCV7VNOwvT0h04ayzPGtpygyjEr6EylTiuxsPkXmOSH4PRtaIkR4LgRX+eAoyiTpzW3SxaQzQ0qqVUqihKSLoPrRP1H2u7kghD7RVi4ViCItWNJZJPo0THKuJZOGzJiUKRMDg/GAt370rajGomPGdLbgzHSb17/xZzm4ucVaMeaeyac4evUBXv8rP8Xa6iqjlRGLUDHY0BzlANPtBa//hf/A5cePcsXVxzh8eIv3vucW7rjzc5yfVGwd3SIfSKSNTOfN3hNruQsLIclzm+h3KonSYgholeNdh5JpFJ+4SKk0FFI8pkT5olvgkWV9ukz2T3FlnUv2rzRiF73Wo+vxJuz9WoJbpRSE2OF80orImO3FshES6IkoevlrKmUS6MgTY0OIHkl/QNWGGNPhzbfJWTM579hYX8PVkqgjgqQ7F0JhsjJFJF+gjUkZiB5tLVoJopBokSapiqTxDn38BKQnUHAd0hiUiCgJSqb6OGWuxP6ACkIvUYopIkOKZIoGEDLJHlLCl2U8XEEbgYqBu++7k+mZmugUUmXc88j9PLzzKGWRc+zgYVauCMSs4/Z7b8M5z2CQM1wfUKzktF7TesnJ3Yc595lH+ezDt1MMcs6caKhdy3htwHglQ5pAVI7MS3xsk9rSBWQ0KCxW9zwmGZFaEEJCSCrd80Y71x+0U7km0ReskcdToFwiCxwi0afaS0nRa0QghA4hEqMlTQnTwUxJkvu8dTS1RwiDFAolBQSH8zVSpMXStR7fOWSIGJFC5hWCTCuMSEQFpSKhm0H0KBHJjMa1O2TKMhpmrORjXOcJQTKfVUyaZHodlmVK4TKKohji4iINfVwA9nmabVejTdnzMRVd16YPoUu7upapVl/KbKzWBAQSl7QvwqV7Fi0IEEoR+yeE7yUD885Tdw6iIrcKbSBGh9GCaj7BZmCMRgw9VigePbGNoWTl8CpaCqSKtHbBzmSOtTlhoLEyQ+QGNTBsHtpA2Qx0xmJ3gVKQrxQMRwVOtqjdgHdzKteRZYY8V2wODfOqI8YaqTVSW5QJGF32Z4wO0ysum9ohZBKuES+AhYk0YKPvosQ+xexir0tkgS9dL2JvvJ1yttXebr532kYSvAN8vwsALFV8MdGKVeLdN0ECHYiAkhKjBVJ4lBBoKRGEJLAC8C7tKCIihSeXqStC7JAiYK1KhGSjmUwi0+mcczsLhBAMBoPk9JGgZArc975Lnk98ooW1HcLE3oiRfJbWDFI7rGsJEpCSTKeBlxCB0EV8/4GWxqC4oHvQZ7fIGBMV0QVkP221NulcQlRYq9E6kGUpkXemOrxwZKXCO09mJZnWGA15JhitrBCDIordPuyf1JoMqUOktUQolbowJBeezj2qdgityEpBXoiU3S4iedQgFFmm0CZ9kKL3JChXiqgmgiDgOw9RYI0koZWSFIJg0gE9xMe1e8MltMBjX0NKafZcN8tFLfo87b6YIS4XrY6YmA6Z9I51rUnoEGtoFqleM8YQcGRGY1QCRCkhkTHQ9zZISvSUOSQIZGY5XAi0XUsMgqhbjM4pBwqlCybTBW3bMptPWFQzNtZWyfMcY1UvG2iSOlAKXH9uUHofVqu0JYaOjg4V6MVbiuA9LAVFffyEjKks2Y++cEQkUqS8FSV7CgTJlaS1BKGp6wVBBrKiRIika1lOCQmBwhh829B1Dr2a9R2jyGCYhmzSSoalpigUdQVKOogNUknyomQ0zIjSULeKpk56d+c92huMVRitUr6kVeglTzQmqfPy/YX0842R3nCeKB0hdiD83vBs+UT8oqvBgb2QHNn/oADqZpHMCFbtHebarklOGaPQKkeQ4zpo2/7AQgdCEEkTTCEMZVngmil5JtAqYHp0YHB78w6kFKmEERGCY7FbpyyTwjIYZf0hLrJodhkOc4qBwhYDtFpLwUVNx8mHz7KMZ7aZpCwLsswwXhlS13M61xCi6nvASZUYSJY6IRKNoqoafNditWRU5um1inTWMCYhr713dK5NU0ydyrNyYInSQyv63bF/4smko5ESpIrUzYyq6tKUOEBWljTCgwsMFAyKlulkQV40zKYLSMN95ouG6DvyrGM0diAjWk8Az6HLDjBe2WD3/IIHvvAgPhi0HvbnkIAMEa8lSlqMUgjh0NqgTey1PR5jssQQRTGbzZgvZrRtjdIgwn5aQYLufpEt8Bgj2hgQIS0m1zKbTSA6pLBIYfBN2nFyZehCJLM5TdMwKgLCgh1qprMFxJK2iQzsJnPlqboZQhlKeznzyQ7FwGAzxaJqyHJN5VKtvDoYMavnGKEo8wEr63PKUlJXc9omMhqNqOuWUpo0su8865lhNtulntcMiwK9tcX2ufPMFgvqRcTPPJUWtLs1G5ubgMcajfMVg8GAKniijAgTEcojZep+CAteCaL1RBNw0kPoaOcm8YWsJFLjug7XphQCOyxRokYJl2YITU1ZFLT1CGN2kc0Cg+RAtsnJ81O6IMG22NUpZeyIPqBNRIt1hoMBMZynLCxSeIiOzEC2aigGoMwcIRJsIMsiB1cgjBTn84gm77POz2PMgHKUJf2Ibgk0OGeJ2Q6dD6iYnqRGCYxJWqDd3SlRGMZrGbN5WvjNIoUlNfUS/XLxy/aSWOBpeicpigwRBd5FtJCYomCJ7nB4tBQoJSgKTZapHuXd9uzLhOJOdORI56dUVcWiXkBUtLFitCLJDGkX164vS1JURQwaQkP0CVPog6FtJW0n8B7aThBCChKKQdG50O+mpg+pz1DWsHFwi9WNyGzasFjULOqGybwiCIMxmixLhZYPgaAqICB1jzH0Adc6RoMhQkjaLnUVlBapJSmWevL93vnSDbX8lXrvoe+kuAvcRWLva9LfSeeaoijSYTJGhnqELTQ2yLS7hhZiQIjIcFggVRrGZDYtmyzLKGxBUeR92TVMNIwu0DqfjB5Lg7bwe46n2Gm0sQzLAhE8wXlCHYlCUJg1mtbTLCK+NWiR7aWXLd1bjye67ZJY4ERoFh1d05LnFqMEw+GY+WwCdIiYHrHKqP7R5jGmSy3ELoGalKHfXSTKpMUudYu1jqZt8D61xUQ/EVU6BflYk5a5NhEbSQQJkyaqUQdkJvBdABMx1kCbuPWyzwHXUiKznCzPWEwneAJBSPJRhi0HhFCyfW5C1S6YVT71v3MLUtN1U4zRjFczlLLpMFlIlr7apk5uf2MlQhpyldxO9PW3kAIZU3Q09BSMoLBaoESKjE5nm6WrX+3V584nYsRgUDDIFTJCIYY42QIKmxUIbG/aCJS5QevkHhoMkpTY9DbCtlv0ee2RwaBMUXwukeuiFCkAKfZdsBgY5gMUAl+7JL2IaUo8my7Y2DyAio7JfIH0Alc1tK3fD0W6IG7vYq5LYoFrrSmMoXMN7aLBE5nvNmysrfUiG4+xqR3m5i2dawmZILcZIXpypZE+YkUi+QpXpzdYaA5sbDGdVPgqY7qzy3i4yTA3WNHSdQ1N1WGMookBrXOkSwlVnTpL26VkWEwgqJRsumjnyWRcpniLPF/6LGccXGnoOp9UkT6ZGIKXrB5J0tfgYbGoOXv2BNNTDa3fxFrPbMdhLFgrGY4Kmq4lywxFaYEWJxyVq8jtJs61SfQVU4a4QKVRe0y6dwQUpWcwzJnPmj7ENC1wIQPGCGwmqLu0+LXOk1Izgl80LOrtdDBXy8MqGClAOoTQaJMM2m3b4VxD23mWPlSQKC2RMeW8eN8yX1Tpz2TcS9R1012ktUlfoyUiRIrcko8ystgymZ0nVA1WKILon5J9fEjX7YenXtTa+vtZso/zigGrA1Yb5rMZUWgObByg67rU+ouSrBggBLjYUfua0GqiyAldh4+a2rWIINFW4xqL6xShE2TZmNhBu/DYfEiuVjBCgFNUkwZrC6S0xJZU7xOIrUTJjT6AaAXRdeAUKhbI2gKgjUn54v3o2Nc1uJZQdwQfsGZEITOE1FRVQyZHaG3IsoZ8bY2qqji5m7ye3aLBN57GdLRti8lSy3FgktMeIZDK0bpI9MkQolSPO0991fQIR+BEwGpNkSnqSuD68FF6RZ6QEalSeeJ6coT3SQxVNzOk7DtKSqB0RIvU2pMAwiGi6CMd+m5WP2lMQlxJXXdJQ6JStEfjes6p3BeaiXaL4WANoySurakXFavFJo1v2D1TUdpjZANBVTUIqZmqswgS08h3KaLjYq9LY4ETCGGBFDYZFpRnMBgRXWJMurbDyDJZvWxkHnruusmItJSDnK5OljCjLUpEXCdYlB1FucZiJtg4MmJ9s2AwtHR+xnC0QtfCeDzGWo33jrywQGo/FvIIdV2zYlZpejrEyI6Q2YQYUuux9jVWpyCghV8wKjIYpZ3GO5F2uS4wXsvouvSY1bHjwGqKnbs8G+Jcw2R2iqrdpW6m7M7PkQWHDxKdO3Qm0Cai8BiXBlzOBzIL6oKndcKghyRDNRJrNUZJ2tBLb8VS3UjSYquQnOohyZOXpm+hBEpJssxgVD8LILXslFc4XPpQx4ASMmFleh0QQNs6pACbJxKDkiado3SaaYTgOflQRAbL8WNHUblg12+ze66lKFbYPv0wh48eQSvFottlZW2Dc+H8XlDTsha/2OuSWOBSwmhkUDJjZXCYtvXcfssnEWiGwzEywmKSopKH5QCft0nN5z2amA4qMWWajMZjiIYoMibTmhMnTuC9oDWnyIfruCiItFSNQ2vJ9vb5JIiKHiEDWpPKhL5Pe7J6aK/ven4HhsMhMUbaNr3hTbP/Os5MNW3bIhWsrIxAQ5CpvViFOcGlA9uZRdrJhuFYWph6Tq492UAyWj+YwvxnFSdPzol4yjJjuFIgVA/OUhZlACGJaCQpbBRAa8mwKGlzwSLrIDOURUlRpH5/Xmg2NkcorVk09V5qgRQRm6XYupQTkxakkgGtZdLvxKR2NCYDS1IyhsDudEGISWE5KFMoJ0JRLVpMlve8JMgyi3OOa25YxbsZ29XnkASccpihpmGHA1cquvgoAYFdi5xvzyGjpus80QuKfD8B4GKuS2KBCyGwJkerAiMzBqXi6FFBXTWpBg4hLSzvKQc5lZqneLoYyZRME7EYCMElmgIKomVWpUOn94LxMLC2ZdEmJMG9TPSuYrg/WEC4PXtVJsXevQkR9xZ5WVqWSbTOPbYf2zmDatMHtlxLTwPvk7teVIoQHpstbpp0iBQ+EJaDD6FZXV9jNq04vztlVs8SUrGC2jqUjmQy9YPV0sQgBEiPEJIoJE4mu5iRimgyskySWYWRqbPho8dmHS5aMpthbYaWEdoaokVKkdSRAqRKab9J4diHk8ok9A39gs+yYj/CrqdCIwUxKLS1KcNGpvOR1h3CLFJNr1MqsJAJyJt0NYIQRPJg+ohXLVoXfaiq680tF68HF4/HHfH3dQkhzgBz4Ow/9L38Fdcml+Z9waV7b/9f3NfxGOPW/+gvXRILHEAIcUuM8Vn/0Pfxl69L9b7g0r23S+m+LgmEyZeuL11/X9eXFviXrv9fX5fSAv+lf+gb+GuuS/W+4NK9t0vmvi6ZGvxL15euv4/rUtrBv3R96fo7v/7f9s4eNIogDMPPi5AUaTQKIeVFbFLJIZJCUopJE0srU1jaWhykSatgI4iFIEQL7cRrBH8aK0Ut8mOhiZpGMFcItop8FjOXLEfWnLCZb1nmgWOXueH2Zebl5ue4ebPBM43G3eCSLsQsny1JnRro2Za0HnOH3sWycUnPJW3G67GDPqcCHfck9SRtFMr21aHArdiGa5LaDtqWVVFmU6XsnrLk8CIcR/UZmAJGgFVg2lnTNnBioOwG0In3HeB6Ah2zQBvYOEgHMA88JfzhfAZ446BtGbi2T93p2K+jQCv295FU/en9DX4W2DKzL2b2C3hEyPipGwvASrxfAS4e9gPN7BXwY0gdC8B9C7wGjkqaTKytjN3MJjP7CvQzm5LgbfD/zvNJgAHPJL2PMSsAE7Z32P93YMJHWqmOurRjJZlNVeJt8DpyzszawBxwVdJs8U0L46773mpddBS4A5wEThNS+W76ygl4G3yoPJ+UmNm3eO0BjwnD6U5/yI/XnpO8Mh3u7WhmO2b2x8I5EHfZm4a4avM2+FvglKSWpBFCgGzXS4ykMYWwWySNAecJ2UNdYDFWWwSe+Cgs1dEFLsfdlBngZ2Eqk4SBOf9gZtMlSaOSWgyR2VQpqVaz/1iRzwOfCKvrJWctU4QV/yrwoa8HOA68BDaBF8B4Ai0PCUP9b8K89UqZDsLuye3YhuvAGQdtD+Kz1wimnizUX4raPgJzKfs0/1SfaTTeU5RM5lDJBs80mmzwTKPJBs80mmzwTKPJBs80mmzwTKP5C8eYqmR86bIsAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "from PIL import Image\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 使用海报图像和不使用海报图像的文件路径不同，处理方式相同\n",
    "use_poster = True\n",
    "if use_poster:\n",
    "    rating_path = \"./work/ml-1m/new_rating.txt\"\n",
    "else:\n",
    "    rating_path = \"./work/ml-1m/ratings.dat\"\n",
    "    \n",
    "with open(rating_path, 'r') as f:\n",
    "    data = f.readlines()\n",
    "    \n",
    "# 从新的rating文件中收集所有的电影ID\n",
    "mov_id_collect = []\n",
    "for item in data:\n",
    "    item = item.strip().split(\"::\")\n",
    "    usr_id,movie_id,score = item[0],item[1],item[2]\n",
    "    mov_id_collect.append(movie_id)\n",
    "\n",
    "# 根据电影ID读取图像\n",
    "poster_path = \"./work/ml-1m/posters/\"\n",
    "\n",
    "# 显示mov_id_collect中第几个电影ID的图像\n",
    "idx = 1\n",
    "\n",
    "poster = Image.open(poster_path+'mov_id{}.jpg'.format(str(mov_id_collect[idx])))\n",
    "# poster = poster.resize([64, 64])\n",
    "plt.figure(\"Image\") # 图像窗口名称\n",
    "plt.imshow(poster)\n",
    "plt.axis('on') # 关掉坐标轴为 off\n",
    "plt.title(\"poster with ID {}\".format(mov_id_collect[idx])) # 图像题目\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 构建数据读取器\n",
    "\n",
    "至此我们已经分别处理了用户、电影和评分数据，接下来我们要利用这些处理好的数据，构建一个数据读取器，方便在训练神经网络时直接调用。\n",
    "\n",
    "首先，构造一个函数，把读取并处理后的数据整合到一起，即在rating数据中补齐用户和电影的所有特征字段。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数据集总数据数： 1000209\n"
     ]
    }
   ],
   "source": [
    "def get_dataset(usr_info, rating_info, movie_info):\n",
    "    trainset = []\n",
    "    # 按照评分数据的key值索引数据\n",
    "    for usr_id in rating_info.keys():\n",
    "        usr_ratings = rating_info[usr_id]\n",
    "        for movie_id in usr_ratings:\n",
    "            trainset.append({'usr_info': usr_info[usr_id],\n",
    "                             'mov_info': movie_info[movie_id],\n",
    "                             'scores': usr_ratings[movie_id]})\n",
    "    return trainset\n",
    "\n",
    "dataset = get_dataset(usr_info, rating_info, movie_info)\n",
    "print(\"数据集总数据数：\", len(dataset))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "接下来构建数据读取器函数load_data()，先看一下整体结构："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import random\n",
    "def load_data(dataset=None, mode='train'):\n",
    "    \n",
    "    \"\"\"定义一些超参数等等\"\"\"\n",
    "    \n",
    "    # 定义数据迭代加载器\n",
    "    def data_generator():\n",
    "        \n",
    "        \"\"\" 定义数据的处理过程\"\"\"\n",
    "        \n",
    "        data  = None\n",
    "        yield data\n",
    "        \n",
    "    # 返回数据迭代加载器\n",
    "    return data_generator\n",
    "        "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "我们来看一下完整的数据读取器函数实现，核心是将多个样本数据合并到一个列表（batch），当该列表达到batchsize后，以yield的方式返回（Python数据迭代器）。\n",
    "\n",
    "在进行批次数据拼合的同时，完成数据格式和数据尺寸的转换：\n",
    "\n",
    "* 由于飞桨框架的网络接入层要求将数据先转换成np.array的类型，再转换成框架内置变量tensor的类型。所以在数据返回前，需将所有数据均转换成np.array的类型，方便后续处理。\n",
    "* 每个特征字段的尺寸也需要根据网络输入层的设计进行调整。根据之前的分析，用户和电影的所有原始特征可以分为四类，ID类（用户ID，电影ID，性别，年龄，职业）、列表类（电影类别）、文本类（电影名称）和图像类（电影海报）。因为每种特征后续接入的网络层方案不同，所以要求他们的数据尺寸也不同。这里我们先初步的了解即可，待后续阅读了模型设计章节后，将对输入输出尺寸有更好的理解。\n",
    "\n",
    "数据尺寸的说明：\n",
    "1. ID类（用户ID，电影ID，性别，年龄，职业）处理成（256）的尺寸，以便后续接入Embedding层，数值256是batchsize。\n",
    "2. 列表类（电影类别）处理成（256,6）的尺寸，数值6是电影最多的类别个数，以便后续接入全连接层。\n",
    "3. 文本类（电影名称）处理成（256,1,15）的尺寸，15是电影名称的最多单词数，以便接入2D卷积层。2D卷积层要求输入数据为四维，对应到图像处理的场景，各个维度的含义是【批次大小，通道数、图像的长、图像的宽】，其中RGB的彩色图像是3通道，灰度图像是单通道。在此处理文本的场景，我们使用2D卷积层需要将输入处理成其所需要的维度数量。因为embedding函数会在输入Tensor shape的最后一维后面添加embedding_dim的维度做为输出的Shape，即当输入为（256,1,15），嵌入向量大小为32时，embedding函数会输出（256,1,15,32），这正好是2D卷积层所需要维度数量。\n",
    "4. 图像类（电影海报）处理成（256,3,64,64）的尺寸， 以便接入2D卷积层。图像的原始尺寸是180\\*270彩色图像，使用resize函数压缩成64\\*64的尺寸，减少网络计算。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import random\n",
    "use_poster = False\n",
    "def load_data(dataset=None, mode='train'):\n",
    "    \n",
    "    # 定义数据迭代Batch大小\n",
    "    BATCHSIZE = 256\n",
    "\n",
    "    data_length = len(dataset)\n",
    "    index_list = list(range(data_length))\n",
    "    # 定义数据迭代加载器\n",
    "    def data_generator():\n",
    "        # 训练模式下，打乱训练数据\n",
    "        if mode == 'train':\n",
    "            random.shuffle(index_list)\n",
    "        # 声明每个特征的列表\n",
    "        usr_id_list,usr_gender_list,usr_age_list,usr_job_list = [], [], [], []\n",
    "        mov_id_list,mov_tit_list,mov_cat_list,mov_poster_list = [], [], [], []\n",
    "        score_list = []\n",
    "        # 索引遍历输入数据集\n",
    "        for idx, i in enumerate(index_list):\n",
    "            # 获得特征数据保存到对应特征列表中\n",
    "            usr_id_list.append(dataset[i]['usr_info']['usr_id'])\n",
    "            usr_gender_list.append(dataset[i]['usr_info']['gender'])\n",
    "            usr_age_list.append(dataset[i]['usr_info']['age'])\n",
    "            usr_job_list.append(dataset[i]['usr_info']['job'])\n",
    "\n",
    "            mov_id_list.append(dataset[i]['mov_info']['mov_id'])\n",
    "            mov_tit_list.append(dataset[i]['mov_info']['title'])\n",
    "            mov_cat_list.append(dataset[i]['mov_info']['category'])\n",
    "            mov_id = dataset[i]['mov_info']['mov_id']\n",
    "\n",
    "            if use_poster:\n",
    "                # 不使用图像特征时，不读取图像数据，加快数据读取速度\n",
    "                poster = Image.open(poster_path+'mov_id{}.jpg'.format(str(mov_id)))\n",
    "                poster = poster.resize([64, 64])\n",
    "                if len(poster.size) <= 2:\n",
    "                    poster = poster.convert(\"RGB\")\n",
    "\n",
    "                mov_poster_list.append(np.array(poster))\n",
    "\n",
    "            score_list.append(int(dataset[i]['scores']))\n",
    "            # 如果读取的数据量达到当前的batch大小，就返回当前批次\n",
    "            if len(usr_id_list)==BATCHSIZE:\n",
    "                # 转换列表数据为数组形式，reshape到固定形状\n",
    "                usr_id_arr = np.array(usr_id_list)\n",
    "                usr_gender_arr = np.array(usr_gender_list)\n",
    "                usr_age_arr = np.array(usr_age_list)\n",
    "                usr_job_arr = np.array(usr_job_list)\n",
    "\n",
    "                mov_id_arr = np.array(mov_id_list)\n",
    "\n",
    "                mov_cat_arr = np.reshape(np.array(mov_cat_list), [BATCHSIZE, 6]).astype(np.int64)\n",
    "                mov_tit_arr = np.reshape(np.array(mov_tit_list), [BATCHSIZE, 1, 15]).astype(np.int64)\n",
    "\n",
    "                if use_poster:\n",
    "                    mov_poster_arr = np.reshape(np.array(mov_poster_list)/127.5 - 1, [BATCHSIZE, 3, 64, 64]).astype(np.float32)\n",
    "                else:\n",
    "                    mov_poster_arr = np.array([0.])\n",
    "                    \n",
    "                scores_arr = np.reshape(np.array(score_list), [-1, 1]).astype(np.float32)\n",
    "                \n",
    "                # 返回当前批次数据\n",
    "                yield [usr_id_arr, usr_gender_arr, usr_age_arr, usr_job_arr], \\\n",
    "                       [mov_id_arr, mov_cat_arr, mov_tit_arr, mov_poster_arr], scores_arr\n",
    "                \n",
    "                # 清空数据\n",
    "                usr_id_list, usr_gender_list, usr_age_list, usr_job_list = [], [], [], []\n",
    "                mov_id_list, mov_tit_list, mov_cat_list, score_list = [], [], [], []\n",
    "                mov_poster_list = []\n",
    "    return data_generator"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "load_data()函数通过输入的数据集，处理数据并返回一个数据迭代器。\n",
    "\n",
    "我们将数据集按照8:2的比例划分训练集和验证集，可以分别得到训练数据迭代器和验证数据迭代器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "数据集总数量： 1000209\n",
      "训练集数量： 800167\n",
      "验证集数量: 200042\n"
     ]
    }
   ],
   "source": [
    "dataset = get_dataset(usr_info, rating_info, movie_info)\n",
    "print(\"数据集总数量：\", len(dataset))\n",
    "\n",
    "trainset = dataset[:int(0.8*len(dataset))]\n",
    "train_loader = load_data(trainset, mode=\"train\")\n",
    "print(\"训练集数量：\", len(trainset))\n",
    "\n",
    "validset = dataset[int(0.8*len(dataset)):]\n",
    "valid_loader = load_data(validset, mode='valid')\n",
    "print(\"验证集数量:\", len(validset))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "数据迭代器的使用方式如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "用户ID数据尺寸 (256,)\n",
      "电影ID数据尺寸 (256,) , 电影类别genres数据的尺寸 (256, 6) , 电影名字title的尺寸 (256, 1, 15)\n"
     ]
    }
   ],
   "source": [
    "for idx, data in enumerate(train_loader()):\n",
    "    usr_data, mov_data, score = data\n",
    "    \n",
    "    usr_id_arr, usr_gender_arr, usr_age_arr, usr_job_arr = usr_data\n",
    "    mov_id_arr, mov_cat_arr, mov_tit_arr, mov_poster_arr = mov_data\n",
    "    print(\"用户ID数据尺寸\", usr_id_arr.shape)\n",
    "    print(\"电影ID数据尺寸\", mov_id_arr.shape, \", 电影类别genres数据的尺寸\", mov_cat_arr.shape, \", 电影名字title的尺寸\", mov_tit_arr.shape)\n",
    "    break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 数据处理完整代码\n",
    "\n",
    "到这里，我们已完成了ml-1m数据读取和处理，接下来，我们将数据处理的代码封装到一个Python类中，完整实现如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "##Total dataset instances:  1000209\n",
      "##MovieLens dataset information: \n",
      "usr num: 6040\n",
      "movies num: 3883\n",
      "打印用户ID，性别，年龄，职业数据的维度：\n",
      "(256,)\n",
      "(256,)\n",
      "(256,)\n",
      "(256,)\n",
      "打印电影ID，名字，类别数据的维度：\n",
      "(256,)\n",
      "(256, 6)\n",
      "(256, 1, 15)\n",
      "(1,)\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "import numpy as np\n",
    "from PIL import Image\n",
    "\n",
    "class MovieLen(object):\n",
    "    def __init__(self, use_poster):\n",
    "        self.use_poster = use_poster\n",
    "        # 声明每个数据文件的路径\n",
    "        usr_info_path = \"./work/ml-1m/users.dat\"\n",
    "        if use_poster:\n",
    "            rating_path = \"./work/ml-1m/new_rating.txt\"\n",
    "        else:\n",
    "            rating_path = \"./work/ml-1m/ratings.dat\"\n",
    "\n",
    "        movie_info_path = \"./work/ml-1m/movies.dat\"\n",
    "        self.poster_path = \"./work/ml-1m/posters/\"\n",
    "        # 得到电影数据\n",
    "        self.movie_info, self.movie_cat, self.movie_title = self.get_movie_info(movie_info_path)\n",
    "        # 记录电影的最大ID\n",
    "        self.max_mov_cat = np.max([self.movie_cat[k] for k in self.movie_cat])\n",
    "        self.max_mov_tit = np.max([self.movie_title[k] for k in self.movie_title])\n",
    "        self.max_mov_id = np.max(list(map(int, self.movie_info.keys())))\n",
    "        # 记录用户数据的最大ID\n",
    "        self.max_usr_id = 0\n",
    "        self.max_usr_age = 0\n",
    "        self.max_usr_job = 0\n",
    "        # 得到用户数据\n",
    "        self.usr_info = self.get_usr_info(usr_info_path)\n",
    "        # 得到评分数据\n",
    "        self.rating_info = self.get_rating_info(rating_path)\n",
    "        # 构建数据集 \n",
    "        self.dataset = self.get_dataset(usr_info=self.usr_info,\n",
    "                                        rating_info=self.rating_info,\n",
    "                                        movie_info=self.movie_info)\n",
    "        # 划分数据集，获得数据加载器\n",
    "        self.train_dataset = self.dataset[:int(len(self.dataset)*0.9)]\n",
    "        self.valid_dataset = self.dataset[int(len(self.dataset)*0.9):]\n",
    "        print(\"##Total dataset instances: \", len(self.dataset))\n",
    "        print(\"##MovieLens dataset information: \\nusr num: {}\\n\"\n",
    "              \"movies num: {}\".format(len(self.usr_info),len(self.movie_info)))\n",
    "    # 得到电影数据\n",
    "    def get_movie_info(self, path):\n",
    "        # 打开文件，编码方式选择ISO-8859-1，读取所有数据到data中 \n",
    "        with open(path, 'r', encoding=\"ISO-8859-1\") as f:\n",
    "            data = f.readlines()\n",
    "        # 建立三个字典，分别用户存放电影所有信息，电影的名字信息、类别信息\n",
    "        movie_info, movie_titles, movie_cat = {}, {}, {}\n",
    "        # 对电影名字、类别中不同的单词计数\n",
    "        t_count, c_count = 1, 1\n",
    "\n",
    "        count_tit = {}\n",
    "        # 按行读取数据并处理\n",
    "        for item in data:\n",
    "            item = item.strip().split(\"::\")\n",
    "            v_id = item[0]\n",
    "            v_title = item[1][:-7]\n",
    "            cats = item[2].split('|')\n",
    "            v_year = item[1][-5:-1]\n",
    "\n",
    "            titles = v_title.split()\n",
    "            # 统计电影名字的单词，并给每个单词一个序号，放在movie_titles中\n",
    "            for t in titles:\n",
    "                if t not in movie_titles:\n",
    "                    movie_titles[t] = t_count\n",
    "                    t_count += 1\n",
    "            # 统计电影类别单词，并给每个单词一个序号，放在movie_cat中\n",
    "            for cat in cats:\n",
    "                if cat not in movie_cat:\n",
    "                    movie_cat[cat] = c_count\n",
    "                    c_count += 1\n",
    "            # 补0使电影名称对应的列表长度为15\n",
    "            v_tit = [movie_titles[k] for k in titles]\n",
    "            while len(v_tit)<15:\n",
    "                v_tit.append(0)\n",
    "            # 补0使电影种类对应的列表长度为6\n",
    "            v_cat = [movie_cat[k] for k in cats]\n",
    "            while len(v_cat)<6:\n",
    "                v_cat.append(0)\n",
    "            # 保存电影数据到movie_info中\n",
    "            movie_info[v_id] = {'mov_id': int(v_id),\n",
    "                                'title': v_tit,\n",
    "                                'category': v_cat,\n",
    "                                'years': int(v_year)}\n",
    "        return movie_info, movie_cat, movie_titles\n",
    "\n",
    "    def get_usr_info(self, path):\n",
    "        # 性别转换函数，M-0， F-1\n",
    "        def gender2num(gender):\n",
    "            return 1 if gender == 'F' else 0\n",
    "\n",
    "        # 打开文件，读取所有行到data中\n",
    "        with open(path, 'r') as f:\n",
    "            data = f.readlines()\n",
    "        # 建立用户信息的字典\n",
    "        use_info = {}\n",
    "\n",
    "        max_usr_id = 0\n",
    "        #按行索引数据\n",
    "        for item in data:\n",
    "            # 去除每一行中和数据无关的部分\n",
    "            item = item.strip().split(\"::\")\n",
    "            usr_id = item[0]\n",
    "            # 将字符数据转成数字并保存在字典中\n",
    "            use_info[usr_id] = {'usr_id': int(usr_id),\n",
    "                                'gender': gender2num(item[1]),\n",
    "                                'age': int(item[2]),\n",
    "                                'job': int(item[3])}\n",
    "            self.max_usr_id = max(self.max_usr_id, int(usr_id))\n",
    "            self.max_usr_age = max(self.max_usr_age, int(item[2]))\n",
    "            self.max_usr_job = max(self.max_usr_job, int(item[3]))\n",
    "        return use_info\n",
    "    # 得到评分数据\n",
    "    def get_rating_info(self, path):\n",
    "        # 读取文件里的数据\n",
    "        with open(path, 'r') as f:\n",
    "            data = f.readlines()\n",
    "        # 将数据保存在字典中并返回\n",
    "        rating_info = {}\n",
    "        for item in data:\n",
    "            item = item.strip().split(\"::\")\n",
    "            usr_id,movie_id,score = item[0],item[1],item[2]\n",
    "            if usr_id not in rating_info.keys():\n",
    "                rating_info[usr_id] = {movie_id:float(score)}\n",
    "            else:\n",
    "                rating_info[usr_id][movie_id] = float(score)\n",
    "        return rating_info\n",
    "    # 构建数据集\n",
    "    def get_dataset(self, usr_info, rating_info, movie_info):\n",
    "        trainset = []\n",
    "        for usr_id in rating_info.keys():\n",
    "            usr_ratings = rating_info[usr_id]\n",
    "            for movie_id in usr_ratings:\n",
    "                trainset.append({'usr_info': usr_info[usr_id],\n",
    "                                 'mov_info': movie_info[movie_id],\n",
    "                                 'scores': usr_ratings[movie_id]})\n",
    "        return trainset\n",
    "    \n",
    "    def load_data(self, dataset=None, mode='train'):\n",
    "        use_poster = False\n",
    "\n",
    "        # 定义数据迭代Batch大小\n",
    "        BATCHSIZE = 256\n",
    "\n",
    "        data_length = len(dataset)\n",
    "        index_list = list(range(data_length))\n",
    "        # 定义数据迭代加载器\n",
    "        def data_generator():\n",
    "            # 训练模式下，打乱训练数据\n",
    "            if mode == 'train':\n",
    "                random.shuffle(index_list)\n",
    "            # 声明每个特征的列表\n",
    "            usr_id_list,usr_gender_list,usr_age_list,usr_job_list = [], [], [], []\n",
    "            mov_id_list,mov_tit_list,mov_cat_list,mov_poster_list = [], [], [], []\n",
    "            score_list = []\n",
    "            # 索引遍历输入数据集\n",
    "            for idx, i in enumerate(index_list):\n",
    "                # 获得特征数据保存到对应特征列表中\n",
    "                usr_id_list.append(dataset[i]['usr_info']['usr_id'])\n",
    "                usr_gender_list.append(dataset[i]['usr_info']['gender'])\n",
    "                usr_age_list.append(dataset[i]['usr_info']['age'])\n",
    "                usr_job_list.append(dataset[i]['usr_info']['job'])\n",
    "\n",
    "                mov_id_list.append(dataset[i]['mov_info']['mov_id'])\n",
    "                mov_tit_list.append(dataset[i]['mov_info']['title'])\n",
    "                mov_cat_list.append(dataset[i]['mov_info']['category'])\n",
    "                mov_id = dataset[i]['mov_info']['mov_id']\n",
    "\n",
    "                if use_poster:\n",
    "                    # 不使用图像特征时，不读取图像数据，加快数据读取速度\n",
    "                    poster = Image.open(self.poster_path+'mov_id{}.jpg'.format(str(mov_id[0])))\n",
    "                    poster = poster.resize([64, 64])\n",
    "                    if len(poster.size) <= 2:\n",
    "                        poster = poster.convert(\"RGB\")\n",
    "\n",
    "                    mov_poster_list.append(np.array(poster))\n",
    "\n",
    "                score_list.append(int(dataset[i]['scores']))\n",
    "                # 如果读取的数据量达到当前的batch大小，就返回当前批次\n",
    "                if len(usr_id_list)==BATCHSIZE:\n",
    "                    # 转换列表数据为数组形式，reshape到固定形状\n",
    "                    usr_id_arr = np.array(usr_id_list)\n",
    "                    usr_gender_arr = np.array(usr_gender_list)\n",
    "                    usr_age_arr = np.array(usr_age_list)\n",
    "                    usr_job_arr = np.array(usr_job_list)\n",
    "\n",
    "                    mov_id_arr = np.array(mov_id_list)\n",
    "                    mov_cat_arr = np.reshape(np.array(mov_cat_list), [BATCHSIZE, 6]).astype(np.int64)\n",
    "                    mov_tit_arr = np.reshape(np.array(mov_tit_list), [BATCHSIZE, 1, 15]).astype(np.int64)\n",
    "\n",
    "                    if use_poster:\n",
    "                        mov_poster_arr = np.reshape(np.array(mov_poster_list)/127.5 - 1, [BATCHSIZE, 3, 64, 64]).astype(np.float32)\n",
    "                    else:\n",
    "                        mov_poster_arr = np.array([0.])\n",
    "\n",
    "                    scores_arr = np.reshape(np.array(score_list), [-1, 1]).astype(np.float32)\n",
    "\n",
    "                    # 放回当前批次数据\n",
    "                    yield [usr_id_arr, usr_gender_arr, usr_age_arr, usr_job_arr], \\\n",
    "                           [mov_id_arr, mov_cat_arr, mov_tit_arr, mov_poster_arr], scores_arr\n",
    "\n",
    "                    # 清空数据\n",
    "                    usr_id_list, usr_gender_list, usr_age_list, usr_job_list = [], [], [], []\n",
    "                    mov_id_list, mov_tit_list, mov_cat_list, score_list = [], [], [], []\n",
    "                    mov_poster_list = []\n",
    "        return data_generator\n",
    "\n",
    "# 声明数据读取类\n",
    "dataset = MovieLen(False)\n",
    "# 定义数据读取器\n",
    "train_loader = dataset.load_data(dataset=dataset.train_dataset, mode='train')\n",
    "# 迭代的读取数据， Batchsize = 256\n",
    "for idx, data in enumerate(train_loader()):\n",
    "    usr, mov, score = data\n",
    "    print(\"打印用户ID，性别，年龄，职业数据的维度：\")\n",
    "    for v in usr:\n",
    "        print(v.shape)\n",
    "    print(\"打印电影ID，名字，类别数据的维度：\")\n",
    "    for v in mov:\n",
    "        print(v.shape)\n",
    "    \n",
    "    break\n",
    "    \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "# 总结\n",
    "\n",
    "本节主要介绍了电影推荐数据集ml-1m，并对数据集中的用户数据、电影数据、评分数据进行介绍和处理，将字符串形式的数据转成了数字表示的数据形式，并构建了数据读取器，最终将数据处理和数据读取封装到一个Python类中，如下图所示：\n",
    "<center><img src=\"https://ai-studio-static-online.cdn.bcebos.com/f68016caa41e412e8b78d99568eb254898f2652d897f4e94bb3da60c54e62b39\" width=\"500\" ></center>\n",
    "\n",
    "<center><br>图4：数据处理流程图 </br></center>\n",
    "\n",
    "各数据处理前后格式如下：\n",
    "\n",
    "| 数据分类 | 输入数据样例 | 输出数据样例 |\n",
    "| -------- | -------- | -------- |\n",
    "| **用户数据**     | UserID::Gender::Age::Occupation <br>1::F::1::10     | {'usr_id': 1, 'gender': 1, 'age': 1, 'job': 10}    |\n",
    "| **电影数据**     | MovieID::Title::Genres <br>2::Jumanji (1995)::Adventure\\|Children's\\|Fantasy     | {'mov_id': 2, 'title': [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'category': [4, 2, 5, 0, 0, 0]}     |\n",
    "| **评分数据**     | UserID::MovieID::Rating <br>1::1193::5    | {'usr_id': 1, 'mov_id': 1193, 'score': 5}|\n",
    "| **海报数据**     | \"mov_id\" + MovieID+\".jpg\"格式的图片    | 64\\*64\\*3的像素矩阵|\n",
    "\n",
    "虽然我们将文本的数据转换成了数字表示形式，但是这些数据依然是离散的，不适合直接输入到神经网络中，还需要对其进行Embedding操作，将其映射为固定长度的向量。\n",
    "\n",
    "接下来我们开始个性化电影推荐的第二个部分：模型设计。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "PaddlePaddle 2.0.0b0 (Python 3.5)",
   "language": "python",
   "name": "py35-paddle1.2.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
